CascadeType jpa/hibernate

0

Mam następującą sytuację. Trzy klasy:
-Training

@OneToMany(mappedBy = "training", cascade=CascadeType.ALL ,fetch = FetchType.EAGER)
	@Fetch(value = FetchMode.SUBSELECT)
	@JsonManagedReference(value="act-training")
	private List<Activity> activities;

-Activity

@OneToMany(mappedBy = "activity", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@Fetch(value = FetchMode.SUBSELECT)
	@JsonManagedReference(value="act-series")
	@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	private List<Series> series;

-Series

@ManyToOne(cascade = CascadeType.ALL)
	@JoinColumn(name = "id_activity")
	@JsonBackReference(value="act-series")
	private Activity activity;

Chcę zrobić tak, żęby po zapisie aktywności, zapisywały się odpowiednie serie oraz trening co zresztą uzyskałem działając w ten sposób. Niestety aktywność zapisuje się dwukrotnie. Jak tego uniknąć? Aktywność zapisuje się przy zapisie treningu i drugi raz ta sama aktywność zapisuje się przy wprowadzeniu do bazy danej serii. Chciałbym żeby przy zapisie serii dana aktywność nie zapisywała się dwukrotnie. Ewentualnie jakoś się update'owała. Mogę to jakoś osiągnąć poprzez zmianę CascadeType? Czy jakoś inaczej skonfigurować mam te klasy? ;)

1

Zmień List na Set :) Kuba tu tłumaczy dlaczego :)

0

no wiem, wiem, w sumie ok filmik, coś tam ciekawego mówi ;) ale problemu to nie rozwiązuje :D

0

A jesteś pewien, że nie rozwiązuje i że zapisujesz ten sam obiekt (w sensie ma ten sam hashCode).

0
20:39:32,731 INFO  [stdout] (default task-7) Hibernate: insert into trainings (description, duration, training_date, id_user) values (?, ?, ?, ?)

20:39:32,743 INFO  [stdout] (default task-7) Hibernate: insert into activities (id_exercise, id_training) values (?, ?)

20:39:32,746 INFO  [stdout] (default task-7) Hibernate: insert into activities (id_exercise, id_training) values (?, ?)

20:39:32,752 INFO  [stdout] (default task-7) Hibernate: insert into series (id_activity, repeats, weight) values (?, ?, ?)

No niestety dalej generuje za dużo tych insertów. Bo oczywiście chodzi mi o zapis do bazy, może nie sprecyzowałem też. po właśnie tego drugiego inserta z activities chciałbym się pozbyć. Bo jeden obiekt activity zawiera trening oraz listę czy tam już set obiektów typu series. I zapisując go tworzy 2 inserty jeden dla treningu drugi dla serii. chciałbym żeby jedno i drugie dotyczyło tej samej aktywności.

0

Pokaż kod, który zapisuje do bazy

0

Tak wygląda część na js

activitiesService.save($scope.activities[0]).$promise.then(
                function () {
                    // Broadcast the event to refresh the grid.
                    $rootScope.$broadcast('refreshGrid');
                    // Broadcast the event to display a save message.
                    $rootScope.$broadcast('trainingSaved');
                    $scope.clearForm();
                },
                function () {
                    // Broadcast the event for a server error.
                    $rootScope.$broadcast('error');
                });

a ednpoint wygląda następująco:

@POST
    public Activity createActivity(Activity activity) {
		Long id = activity.getId();
        if (id == null) {
        	Activity activityToSave = new Activity();
        	setActivity(activity, activityToSave);
        	activityRepo.add(activityToSave);
            return activityToSave;
        } else {
        	Activity activityToUpdate = activityRepo.getActivityById(activity.getId());
        	setActivity(activity, activityToUpdate);
        	activity = activityRepo.update(activityToUpdate);
        }
     return activity;
    }

Ewentualnie repozytorium :

public void add(Activity activity){
		em.persist(activity);
	}
	
	public Activity update(Activity activity){
		return em.merge(activity);
	}
	
	public void delete(Activity activity){
		em.remove(em.contains(activity) ? activity : em.merge(activity));
	}
	
	public Activity getActivityById(Long id){
		return em.find(Activity.class, id);
	}

Coś czuję, że słuszna uwaga i tu może leżeć problem, ale coś nie mogę tego ogarnąć.