2013-02-26 68 views
2

我對雙向OneToOne關係有些困惑,雙向關係可能不是可選的。我使用JPA2與Hibernate:非可選雙向OneToOne關係

@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 

如果我檢查市例如,它得到堅持之前,它在正確的地方有一個市長實例,並且這個市長實例有一個關係設置回城市實例。

optional=false只有在城市方面一切都好。

回答

1

這是因爲您對兩側的cascadeAll映射有循環依賴關係。

發生什麼事情是,你正在保存你的城市,保存你的市長,然後保存你的城市,這還沒有被持續(因爲你試圖將它保存在第一位),因此冬眠不知道如何做參考DB中的城市。

您應該嘗試微調市長級別的城市字段級聯以刪除級聯類型持久性。

[編輯] 它似乎也是負責的關係是市長(因爲mappedby在城市類)。我認爲,當你試圖堅持城市,城市應該負責關係(因此mappedBy屬性應該在市長類)

+0

我是否理解正確,我應該刪除'Cascade.ALL'從「公共城市城市」;在市長實體中,並將​​其註釋設置爲「@OneToOne(可選= false)」。我也試過這個,得到同樣的例外。 – speechkey 2013-02-26 11:30:06

+0

這個關係的負責人似乎也是市長(正如城市中的地圖)。我認爲,當你試圖堅持城市,城市應該負責關係(因此mappedBy屬性應該在市長類) – benzonico 2013-02-26 11:34:47

+0

謝謝benzonico,你最後的評論做到了。如果我沒有改變我的代碼中的任何內容,但發送來堅持'市長'(意味着擁有一方),它就像預期的那樣工作。所以我的問題是,爲什麼我不能堅持'城市'(意味着反面),在一對多的關係這是一個普遍的情況? – speechkey 2013-02-26 12:17:57