我想要的单向第3个java类的对象之间的一对一关系:系人心脏,和Person到肝脏。我想的对象共享相同的PK,即每个人都有一个相应的心脏和肝脏,其中person.person_id = heart.heart_id = liver.liver_id。我不想给3个表合并为1,因为每个人都有场的负荷。这里是我的代码(主要是基于公认的答案为这个问题):

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

我建立会话,并执行以下操作:

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

然后,如果我连接起来,人物对象与它的器官,并保存它,我得到一个错误(注:我的时候我只用2类例如人与心脏相同的行为):

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

org.hibernate.id.IdentifierGenerationException:试图从空一到一个属性分配ID:人

然而,它的工作原理如果我设置的关系是双向的:

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

但可以肯定的单向关系,这不应该是必要的?结果 干杯

PS。奇怪的是,我发现它的工作原理(这两个对象保存到数据库)时,我只用2类如人与心,我只是设置链接的其他方式:

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

我不知道为什么这工作(这似乎是合乎逻辑,我认为人是父对象,因为它会自动生成它自己的PK,和其他人使用,所以这就是你应该有设置),但无论如何,我无法弄清楚如何将这种工作方法适用于我的3级的情况...

有帮助吗?

解决方案

我不想告诉你这一点,但你有一个双向的关系存在。该人已到心脏和肝脏的引用,每个那些有一个参考回的人。你已经设置你的心脏和肝脏的标识性的注解是专门说,他们通过委托给他们的人财产得到他们的id属性的值。在你已经表明,不工作的例子,你有没有设置那些家伙人身财产又等,他们显然无法获得其ID值。

您可以设置此关系起来作为一个真正的单向OneToOne,其在休眠注解文档中记载:

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

其他提示

  

我没有尝试,但我要说的是......

两侧之间的区别是,Person类没有的 mappedBy 在他的映射。

因此,对于每一个对一,Person具有参考值,即休眠考虑作为正式的一个。相反,在其他对象中,mappedBy指示休眠不使用的价值,只好到该对象并考虑对应的属性在该对象上。


要检查,如果我是正确的,你可以设置只没有mappedBy值,并保存Person对象(因为它是具有级联的一个),看看结果是正确的..; - )

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top