Relacje tabel jpa/hibernate

0

Witam,
mam pytanie, chce stworzyć odpowiednie struktury klas w javie by odwzorować podane w załączniku relacje bazy danych.
Mam problem z tabelą "Serie". Stworzyłem klasę trening oraz ćwiczenie i je połączyłem adnotacją ManyToMany. Tu wszystko działa sprawnie. Ale nie mam pojęcia jak w to włożyć klasę Serie, która byłaby własnie listą serii konkretnego ćwiczenia w danym treningu. Chce obejśc to bez tworzenia osobnej klasy odpowiadającej za tabelę "trening_cwiczenia".
relacje.png

Myślę, że w miarę jasno to przedstawiłem. Z góry dzięki za pomoc, w razie jakichś pytań, rozwieje niejasności. ;) Nie wiem jak dogłębniej mógłbym to ująć.

Pozdrawiam ;)

2

Moim zdaniem nie powinieneś unikać dodatkowej klasy. Ja bym jedynie nieco zmienił jej nazwę. Zamiast trening_cwiczenia nazwij to aktywność. To Ci daje bardzo ładny model dziedzinowy: Każdy trening zawiera wiele aktywności, każda aktywność to konkretne ćwicznie, realizowane w ramach wielu serii. Zmieniasz adnotacje pomiędzy treningiem a aktywnością na @OneToMany i pięknie to będzie śmigać.

0

Dzięki wielkie, zastanawiałem się właśnie nad podobną opcją. To co proponujesz jest rzeczywiście ciekawym rozwiązaniem i pewnie takie zaimplementuje. Ciekawy też po prostu byłem czy w jakiś rozsądny sposób da się to zrobić w taki sposób, aby nie dodawać jednak tej osobnej klasy z aktywnościami, ale proste rozwiązania są w sumie najlepsze :D nie ma co kombinować za bardzo. Dzięki wielkie za odpowiedź ;)

0

Niestety mam problem z dołączeniem klasy series do reszty schematu. Wydaje mi się, ze wszystko robię poprawnie, niestety pojawia się syntax error przy tworzeniu tabeli series w bazie. Klasa Activity oraz series wyglądają następująco:

@Entity
@Table(name = "activities")
public class Activity {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name = "activity_id")
	private Long id;
	@ManyToOne
	@JoinColumn(name = "id_training")
	private Training training;
	@ManyToOne
	@JoinColumn(name = "id_exercise")
	private Exercise exercise;
	
	@OneToMany(mappedBy = "activity")
	private List<Series> series;
@Entity
@Table(name = "series")
public class Series implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "series_id")
	private Long Id;
	private Integer weight;
	private Integer repeat;
	
	@ManyToOne
	@JoinColumn(name = "id_activity")
	private Activity activity;

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'repeat integer, weight integer, id_activity bigint, primary key (series_id))' at line 1

Nie mam zbytnio pojęcia jak to zmienić, żeby poprawnie zadziałało ;)

1

"repeat" jest słowem kluczowym w składni MySQL, zmień nazwę np. na _repeat i powinno zadziałać (w sensie nazwę samej kolumny, w Javie może zostać).
Taka jeszcze drobna uwaga: w większości konwencji nazewniczych, z którymi się spotkałem klucz główny w tabeli nazywa się po prostu "id", nazwy typu {nazwa_tabeli}_id stosuje się raczej dla kluczy obcych.

0

Zgadza się, chodziło o repeat, wszystko gra teraz. ;) Dzięki wielkie za pomoc i uwagi. ;)

1

Mała uwaga do tego co napisał @dymul. Nie trzeba zmieniać nazwy kolumny na jakąś inną, a tym bardziej na nazwę zaczynającą się od _ (popatrz na to z perspektywy siebie za 10 lat, dlaczego uzyłeś tego znaku w nazwie, pamiętasz?).

Można napisać tak:

class Serie{
    //...

   @Column(name="\"repreat\"")
   private int repreat;
}

Taki zapis spowoduje, że wygenerowany SQL będzie poprawny.

0

Pojawił się kolejny problem. Tym razem bardziej z javascriptem. Mam powiedzmy stronę główną. W jednym divie podpięty jest dany controller. do tego diva, po zdarzeniu kliknięcia dodawana jest treść z innego pliku. I niestety ta treść niby jest dodawana prawidłowo wizualnie do tego diva, lecz nie jest pod kontrolą jego kontrolera. A rozchodzi się żeby była jednak. :D

Część js:

$scope.addNextExerciseCl = function () {
    	setTimeout(function(){
    	$rootScope.$broadcast('addNextExerciseCl');
    	}, 100);
    };
    $scope.$on('addNextExerciseCl', function (event) {
    	alert($scope.bodyPart.name);
    	alert($scope.exercise.name);
    	alert('click');
    	$rootScope.$broadcast('clEv', $scope.bodyPart, $scope.exercise);
    });

$scope.addNextExerciseMU = function () {
    	$rootScope.$broadcast('addNextExerciseMU');
    };
    $scope.$on('addNextExerciseMU', function (event) {
    	
    	
    	alert('mouseUp')
    	alert($scope.num);
    	$.post('nextExercise', {num : $scope.num},
				function(result){
    		
    		$( "#addTrainingForm" ).append(result);
					alert(result);
				});
    	$scope.num++;
    	
    });

Zastanawiałem się nad użyciem innerHtml, ale jakoś mi to rozwiązanie ostatecznie nie podchodzi.

Część treści, która jest łądowana po kliknięciu:

<div class= "row">
			<label class="col-md-1 col-md-offset-1 control-label" >Partia:</label>
			<label class="col-md-1 col-md-offset-1 control-label addTrainingBodyPart" ng-bind="bodyPart0.name"></label>
			<label class="col-md-1 col-md-offset-1 control-label">Ćwiczenie:</label>
			<label class="col-md-3 col-md-offset-1 control-label addTrainingExercise" ng-bind="exercise0.name">ćwiczenie</label>
						
		</div>

Javascript obsługujący zmiane bodyPart0 i exercise0.:

$scope.$on('clEv', function (event, bodyPart, exercise) {
    	setTimeout(function(){
    	alert('formCOntr');
    	alert(bodyPart.name);
    	$scope.bodyPart0 = bodyPart;
    	$scope.exercise0 = exercise;
    	}, 100);
    });

Zaznaczam, że jeśli treść którą ładuje po kliknięciu umieszczę na sztywno na stronie głównej, to dane ładują się poprawnie(chodzi mi o ng-blind). Także ta treść ładowana po prostu nie działa na tym samym kontrolerze co reszta, w źródle strony po jej dodaniu też się nie wyświetla i nie wiem jak to obejść. Z góry dzięki za pomoc. Troszkę może zawile to wytłumaczyłem :D ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1