Hibernate one-to-one association with a common PK between 3 classes

I want a one-way relationship between objects from 3 Java classes: Person to Heart and Person to Liver. I want the objects to have the same PC, that is, each person has a corresponding heart and liver, where person.person_id = heart.heart_id = liver.liver_id. I do not want to combine 3 tables into 1, because each has many fields. Here is my code (mainly based on the accepted answer to this question ):

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

I am setting up a session and doing the following:

Person jack = new Person();
jack.setName("jack");
Heart heart = new Heart();
heart.setBpm(80);
Liver liver = new Liver();
liver.setHealthy(true);

Then, if I bind a person’s object to it with organs and save it, I get an error message (NOTE: I have the same behavior when I just used 2 classes, for example Person and Heart):

jack.setHeart(heart);
jack.setLiver(liver);
session.save(jack);

org.hibernate.id.IdentifierGenerationException: id null one-to-one: person

, :

jack.setHeart(heart);
heart.setPerson(jack);
jack.setLiver(liver);
liver.setPerson(jack);
session.save(jack);

, , ?

. , , ( ), 2 , . Person and Heart, :

heart.setPerson(jack);
session.save(heart);

, ( , Person , PK, , , ), , 3- ...

+5
2

, . , . , , , Id, . , , , Person , , , Id.

OneToOne, Hibernate:

@Entity
public class Body {
    @Id
    public Long getId() { return id; }

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    public Heart getHeart() {
        return heart;
    }
    ...
}


@Entity
public class Heart {
    @Id
    public Long getId() { ...}
}

, , :

@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;}

   public void setHeart(Heart heart){
      this.heart = heart;
      this.heart.setPerson(this);
   }

   @OneToOne(cascade = CascadeType.ALL)
   @PrimaryKeyJoinColumn
   public Liver getLiver() {return liver;}

   public void setLiver(Liver liver){
      this.liver = liver;
      this.liver.setPerson(this);
   }
   // other getters and setters and constructors
}
+6

, , ....

, Person mappedBy .

, " " Person , Hibernate . , mappedBy Hibernate, , .


, , , mappedBy, Person ( , ), , ..; -)

+1

All Articles