Java 非可选双向OneToOne关系

Java 非可选双向OneToOne关系,java,hibernate,jpa,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=Casca

我对双向
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
仅在城市一侧,则一切正常。

这是因为您对映射具有循环依赖性,而cascadeAll位于两侧

这里发生的事情是,你正在拯救你的城市,这拯救了你的市长,然后拯救了你的城市,这还没有持续(因为你首先试图拯救它),因此hibernate不知道如何在DB中引用城市

您应该尝试在mayor类中微调city字段的级联,以删除级联类型

[编辑]
似乎这段关系的负责人也是市长(因为mappedby属于城市级别)。我认为,当您试图坚持城市时,城市应该对这种关系负责(因此mappedBy属性应该在mayor类中)

我是否正确理解,我应该删除
Cascade,并将其注释设置为
@OneToOne(可选=false)
。我也试过这个,得到了同样的例外。似乎这段关系的负责人也是市长(因为mappedby是城市级别的)。我认为,当你试图坚持这个城市时,这个城市应该对这个关系负责(因此mappedBy属性应该在mayor类中)。谢谢benzonico,你最后的评论是这样说的。如果我不更改代码中的任何内容,而是发送到persist
Mayor
(表示拥有方),它将按预期工作。所以我的问题是,为什么我不能发送到persist
City
(意思是反向的一面),在一对多关系中这是一个常见的情况?