title: Hibernate one-to-one entity association with shared PK between 3 classes
body: <p>I want a <strong>unidirectional</strong> one-to-one relationship between objects of 3 java classes: Person to Heart, and Person to Liver. I want the objects to share the same PK i.e. every person has a corresponding heart and liver, where person.person_id = heart.heart_id = liver.liver_id. I do not want to merge the 3 tables into 1 because each has loads of fields. Here's my code (mostly based on the accepted answer for <a href="https://stackoverflow.com/questions/787698/jpa-hibernate-one-to-one-relationship">this question</a>):</p>
  
  <pre><code>@Entity
  public class Person {
     public long personId;
     private String name;
     public Heart heart;
     public Liver liver;
     // other fields
  
     @Id
     @GeneratedValue
     public long getPersonId() {return personId;}
  
     @OneToOne(cascade = CascadeType.ALL)
     @PrimaryKeyJoinColumn
     public Heart getHeart() {return heart;}
  
     @OneToOne(cascade = CascadeType.ALL)
     @PrimaryKeyJoinColumn
     public Liver getLiver() {return liver;}
  
     // other getters and setters and constructors
  }
  
  
  @Entity
  public class Heart {
     private long heartId;
     private int bpm;
     private Person person;
     // other fields
  
     @Id
     @GenericGenerator(
        name = "generator",
        strategy = "foreign",
        parameters = @Parameter(name = "property", value = "person")
     )
     @GeneratedValue(generator = "generator")
     public long getHeartId() {return heardId;}
  
     @OneToOne(mappedBy="heart")
     @PrimaryKeyJoinColumn
     public Person getPerson() {return person;}
  
     // other getters and setters and constructors
  }
  
  
  @Entity
  public class Liver {
     private long liverId;
     private boolean healthy;
     private Person person;
     // other fields
  
     // the rest uses the same hibernate annotation as Heart
  }
  </code></pre>
  
  <p>I setup the session and do the following:</p>
  
  <pre><code>Person jack = new Person();
  jack.setName("jack");
  Heart heart = new Heart();
  heart.setBpm(80);
  Liver liver = new Liver();
  liver.setHealthy(true);
  </code></pre>
  
  <p>Then if I link up the person object with it's organs, and save it, I get an error (NOTE: I got the same behaviour when I just used 2 classes e.g. Person and Heart):</p>
  
  <pre><code>jack.setHeart(heart);
  jack.setLiver(liver);
  session.save(jack);
  </code></pre>
  
  <blockquote>
    <p>org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: person</p>
  </blockquote>
  
  <p>However it works if I set the relationship both ways:</p>
  
  <pre><code>jack.setHeart(heart);
  heart.setPerson(jack);
  jack.setLiver(liver);
  liver.setPerson(jack);
  session.save(jack);
  </code></pre>
  
  <p>But surely this should not be necessary for unidirectional relationships?<br>
  Cheers  </p>
  
  <p>ps. Oddly enough, I notice it works (saves both objects to the DB) when I just use 2 classes e.g. Person and Heart, and I just set the link the other way:</p>
  
  <pre><code>heart.setPerson(jack);
  session.save(heart);
  </code></pre>
  
  <p>I have no idea why this works (it seems logical to me that Person is the parent object, as it auto-generates it's own PK, and the others use that; so that's all you should have to setup), but anyway I cannot figure out how to apply this working method to my 3-class situation...</p>