CascadeType jpa/hibernate

CascadeType jpa/hibernate
L1
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 7 lat
  • Postów:32
0

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

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

-Activity

Kopiuj
@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

Kopiuj
@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? ;)

Koziołek
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:25 dni
  • Lokalizacja:Stacktrace
  • Postów:6821
1

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


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
KA
@Koziołek dzięki za mega link. To jeden z najlepszych występów jakie widziałam ever!
L1
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 7 lat
  • Postów:32
0

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

Koziołek
Moderator
  • Rejestracja:około 18 lat
  • Ostatnio:25 dni
  • Lokalizacja:Stacktrace
  • Postów:6821
0

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


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
L1
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 7 lat
  • Postów:32
0
Kopiuj
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.

dymul
  • Rejestracja:około 11 lat
  • Ostatnio:ponad rok
  • Postów:182
0

Pokaż kod, który zapisuje do bazy

L1
  • Rejestracja:prawie 10 lat
  • Ostatnio:prawie 7 lat
  • Postów:32
0

Tak wygląda część na js

Kopiuj
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:

Kopiuj
@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 :

Kopiuj
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ąć.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.