非可选的双向OneToOne关系

时间:2013-02-26 11:21:34

标签: java hibernate jpa

我对双向OneToOne关系感到困惑,两端可能不是可选的。我正在使用JPA2和Hibernate:

@Entity
@Table(name = "city")
public class City {

    @Id
    @GeneratedValue
    @Column
    public Long _UID;

    @OneToOne(mappedBy="city", optional=false, orphanRemoval = true, cascade=CascadeType.ALL)
    public Mayor mayor;
}

@Entity
@Table(name = "mayor")
public class Mayor {

    @Id
    @GeneratedValue
    @Column
    public Long _UID;

    @OneToOne(optional=false, cascade=CascadeType.ALL)
    public City city;
}

如果我尝试这个交易:

Mayor m = new Mayor("Ed", "Lee");
City c = new City("San Francisco", 100000);
m.setCity(c);
c.setMayor(m);

EntityTransaction et = this.getEm().get().getTransaction();
et.begin();

this.getEm().get().persist(c);
this.getEm().get().flush();

et.commit();

我得到以下例外:

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: test.persistence.entity.Mayor.city

如果我在City实例被持久化之前检查它,它在正确的位置有一个Mayor实例,而这个Mayor实例的关系设置回City实例

仅在城市一侧使用optional=false一切正常。

1 个答案:

答案 0 :(得分:1)

这是因为你对两侧的cascadeAll的映射都有循环依赖。

会发生什么事情,你正在拯救你的城市,拯救你的市长,然后保存你的城市,这是没有持久的(因为你试图首先保存它),因此休眠不知道如何参考到了DB的城市。

您应该尝试微调市长类中城市字段的级联,以删除级联类型持久性。

[编辑] 似乎关系的责任是市长(因为映射是在城市类中)。我认为,当你试图坚持这个城市时,城市应该负责这个关系(因此mappedBy属性应该在市长级别)