Abhinav Prakash
Abhinav Prakash

Reputation: 107

@OneToMany relationship does not save the primary key of the parent in the children tables

Let there be three JPA Entities. A Person and two one-to-many relations to it. When I'm trying to save the Person AD_P_ID and AC_P_ID foreign keys are always null. The expected value for these fields is the person Id. What am I doing wrong?

  1. Person.java: This contains one to Many relationships with Account and Address Entity classes:

    @Entity
    @Table(name = "A2C_PERSON")
    class Person implements Serializable {
    
        private long id;
    
        private List<Account> acs;
    
        private List<Address> ads;
    
        @OneToMany(cascade=CascadeType.ALL, mappedBy = "person")
        public List<Account> getAccount() {
            return this.acs;
        }
    
        @OneToMany(cascade=CascadeType.ALL, mappedBy = "person")
        public List<Address> getAddress() {
            return this.ads;
        }
    }
    
  2. Account.java

    @Entity
    @Table(name = "A2C_ACCOUNT")
    public class Account implements Serializable {
    
        private long id;
    
        private Person person;
    
        @ManyToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
        @JoinColumn(name = "AC_P_ID")
        public Person getPerson() {
            return this.person;
        }
    }
    
  3. Address.java

    @Entity
    @Table(name = "A2C_ADDRESS")
    public class Address implements Serializable {
    
        private long id;
    
        private Person person;
    
        @ManyToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
        @JoinColumn(name = "AD_P_ID")
        public Person getPerson() {
            return this.person;
        }
    }
    

A code to save the person:

Person p = new Person();

Account ac1 = new Account();
Account ac2 = new Account();
List<Account> acList = new ArrayList<>();
acList.add(ac1);
acList.add(ac2)

Address ad1 = new Adddress();
Address ad2 = new Adddress();
List<Address> adList = new ArrayList<>();
acList.add(ad1);
acList.add(ad2)

p.setAcs(acList);
p.setAds(adList);

personRepo.save(p);

Upvotes: 4

Views: 9256

Answers (2)

Maxim Popravko
Maxim Popravko

Reputation: 4169

@JoinColumn indicates the owner of the relationship.

"MappedBy" indicates the inverse side.

So:

@OneToMany(mappedBy = "parent")
private Collection<Child> childCollection;

will not set parent reference to its child. It is your case. You can set it manually like Maciej adviced, but it will add some boilerplace code.

To set parent reference to its child automatically, you have to define owner of the relationship in the following way.

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn
private Collection<Child> childCollection;

Upvotes: 5

Maciej Kowalski
Maciej Kowalski

Reputation: 26572

For each Address and Account entity you need to set the Person entity. This is mandatory in order for hibernate to save the ids in children:

Person p = new Person();

Account ac1 = new Account();
ac1.setPerson(p);  
List<Account> acList = new ArrayList<>();
acList.add(ac1);

Address ad1 = new Adddress();
ad1.setPerson(p);
List<Address> adList = new ArrayList<>();
acList.add(ad1);

Upvotes: 4

Related Questions