如果A和B 共享同一个主键列 ,则这两个实体 通过使用它们的主键进行连接
,这时就吹响了,您应该改用@PrimaryKeyJoinColumn
@Entitypublic class A implements Serializable { private MutableInt id = new MutableInt(); private B b; public void setIdAsMutableInt(MutableInt id) { this.id = id; } @Id @GeneratedValue public Integer getId() { return id.intValue(); } public void setId(Integer id) { this.id.setValue(id); } @oneToOne(fetch=FetchType.LAZY) @PrimaryKeyJoinColumn @Cascade(CascadeType.SAVE_UPDATe) public B getB() { return b; } public void setB(B b) { b.setIdAsMutableInt(id); this.b = b; }}和B注意 ,* 由于 @PrimaryKeyJoinColumn, 您不需要 mapedBy 属性 *
@Entitypublic class B implements Serializable { private MutableInt id = new MutableInt(); private A a; public void setIdAsMutableInt(MutableInt id) { this.id = id; } @Id public Integer getId() { return id.intValue(); } public void setId(Integer id) { this.id.setValue(id); } @oneToOne(fetch=FetchType.LAZY) @PrimaryKeyJoinColumn public A getA() { return a; } public void setA(A a) { this.a = a; }}测试(您可以测试是否需要)
A a = new A();B b = new B();a.setB(b);Serializable id = session.save(a);b = (B) session .createQuery("from B b left join fetch b.a where b.id = :id") .setParameter("id", id) .list() .get(0);Assert.assertEquals(b.getId(), b.getA().getId());注意,我使用MutableInt字段(由Integer属性 封装 )而不是Integer,因为Integer
是不可变的类型,A和B都共享SAME分配的ID
但是,如果A和B 通过使用除主键之外的其他键进行连接 ,则应使用@JoinColumn和maptedBy(双向关系,右),如下所示
@Entitypublic class A implements Serializable { private Integer id; private B b; @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @oneToOne(fetch=FetchType.LAZY, mappedBy="a") @JoinColumn(name="B_ID") @Cascade(CascadeType.SAVE_UPDATe) public B getB() { return b; } public void setB(B b) { this.b = b; }}和B
@Entitypublic class B implements Serializable { private Integer id; private A a; public void setIdAsMutableInt(MutableInt id) { this.id = id; } @Id @GeneratedValue public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @oneToOne(fetch=FetchType.LAZY) public A getA() { return a; } public void setA(A a) { this.a = a; }}去测试
A a = new A();B b = new B(); a.setB(b);b.setA(a);Serializable id = session.save(a);b = (B) session .createQuery("from B b left join fetch b.a where b.id = :id") .setParameter("id", id) .list() .get(0);通过使用所有者方B, 您将获得两个select语句。 这是因为B表 不包含任何指向表A的外键列, 但是通过使用
“从A左连接获取ab,其中a.id =:id”
您将 仅 获得 一条select语句, 因为A知道如何使用其B_ID外键列来检索其联接的B。



