javahibernatehibernate-onetomany

save an object with childs in Hibernate/JPA - @OneToMany


In Hibernate I want to save an object that has a child.In parent Object I have Set of other classes that are child. The parent hase a @OneToMany relationship with the child.

parent :

@Entity
public class TalentIdentitySetting {

 @OneToMany(fetch = FetchType.LAZY, mappedBy = "setting", cascade = CascadeType.ALL, orphanRemoval = true)
 private Set<TalentIdentitySettingPower> settingPowers;

 @OneToMany(fetch = FetchType.LAZY, mappedBy = "setting", cascade = CascadeType.ALL, orphanRemoval = true)
 private Set<TalentIdentitySettingSpeciality> settingSpecialities;

}

child :

@Entity
public class TalentIdentitySettingPower {

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "IDENTITY_SETTING_ID", nullable = false)
 private TalentIdentitySetting setting;

 @ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "POWER_ID", nullable = false)
 private BasePower power;

}

how I can save parent and child together in one transaction. This is my problem; When the child wants to be saved the parent has not been saved yet and say parent key not found. In fact, hibernate should save the parent first and then the child.

please help me.


Solution

  • I believe your JPA Annotation is correct, this is likely that your TalentIdentitySettingPower.setting is not being set before it saved

    Let say if you have the following code

            TalentIdentitySetting setting = new TalentIdentitySetting();
            HashSet<TalentIdentitySettingPower> powers = new HashSet<>();
            powers.add(new TalentIdentitySettingPower());
            powers.add(new TalentIdentitySettingPower());
            powers.add(new TalentIdentitySettingPower());
            setting.setSettingPowers(powers);
            repository.save(setting);
    

    This will fail and complain about null-value issue

    If you add a constructor method in TalentIdentitySettingPower

        public TalentIdentitySettingPower(TalentIdentitySetting setting) {
            this.setting = setting;
        }
    

    and

            TalentIdentitySetting setting = new TalentIdentitySetting();
            HashSet<TalentIdentitySettingPower> powers = new HashSet<>();
            powers.add(new TalentIdentitySettingPower(setting));
            powers.add(new TalentIdentitySettingPower(setting));
            powers.add(new TalentIdentitySettingPower(setting));
            setting.setSettingPowers(powers);
            repository.save(setting);
    

    This will successfully save the value into database.

    Base on your sample, I create an application https://github.com/hepoiko/stack-63703687