2010-05-15 68 views
9

Hibernate不允許我使用整數字段來保存包含空嵌入對象的對象。舉例來說,如果我有一個東西叫類,看起來像這樣Hibernate不允許帶int字段的嵌入對象爲空?

@Entity 
public class Thing { 

    @Id 
    public String id; 

    public Part part; 

} 

,其中部分是一個可嵌入類,它看起來像這樣

@Embeddable 
public class Part { 

    public String a;  

    public int b; 

} 

然後試圖堅持用空部分原因一件事對象Hibernate拋出一個異常。特別是,該代碼

Thing th = new Thing(); 
th.id = "thing.1"; 
th.part = null; 
session.saveOrUpdate(th); 

導致Hibernate拋出此異常

org.hibernate.PropertyValueException: not-null property references a null or transient value: com.ace.moab.api.jobs.Thing.part 

我的猜測是,這是發生,因爲部分是嵌入類等Part.a和Part.b只是列在Thing數據庫表中。由於Thing.part爲null,Hibernate希望爲thing.1的行設置Part.a和Part.b列值爲null。然而,Part.b是一個整數,Hibernate將不允許數據庫中的整數列爲空。這是什麼導致異常,對不對?

所以我正在尋找解決這個問題的解決方法。我注意到讓Part.b成爲Integer而不是int似乎可行,但出於某些原因,我不會讓你感到厭煩,這對我們來說不是一個好的選擇。謝謝!

回答

7

我發現了另一種解決方法,並認爲我會分享它。原來,如果你讓int列可以爲空,那麼Hibernate不會拋出PropertyValueException。

@Column(nullable = true) 
public Integer b; 

這適用於我們,因爲我們的休眠激活的應用是觸摸了數據庫,所以我們可以保證,b爲null,只有當部分是空的嘛。雖然null部分的建議和Integer wrapper類型的使用是很好的建議,但由於我沒有真正控制的很多原因,將列設置爲空可以最適合我們。謝謝,但我希望這可以幫助別人。

+0

當'b'是一個原語時,你的int如何爲空? – 2015-04-03 17:51:48

+0

你應該使用一個包裝類(Integer)來處理任何可以爲空的東西...... – Amalgovinus 2016-08-10 21:02:03

1

你對所發生的事情絕對正確。當嵌入類的對象爲null時,Hibernate通過在數據庫中使其所有列爲空來表示這種情況;不幸的是,這意味着Hibernate無法區分一個null可嵌入對象和一個全空值的可嵌入對象。

據我所知,如果你不能使字段爲空(通過使它成爲Integer,正如你猜測的那樣),唯一的方法就是創建一個自定義的Hibernate類型。應該是可行的,但這樣做會很痛苦。事實上,它可能會比不管什麼原因是你不能使用Integer更糟 - 那麼究竟是什麼原因呢?

3

很不舒服,是的。您可以將默認值設置爲part領域:

private Part part = new Part(); 

甚至

private Part part = Part.NULL_PART; 

(見Null object patern

請記住,如果你的@Embeddable類不包含原始(它有一個默認值),並且你保存了一個全部爲null的對象,整個結構將作爲null被保存在數據庫中,因爲沒有辦法讓hibernate生成e數據庫中的差異是否沒有對象,或者是否有空。要解決這個問題,如果出現這種情況,您必須創建一個虛擬字段(最好是boolean)。

相關問題