2011-01-13 80 views
6

我有一個表,父對象有一個可選的多對一關係。問題是表被設置爲默認fkey列爲0.休眠多對一外鍵默認0

當選擇時,使用fetch =「join」等等,fkey上的默認值0被用於反覆嘗試以反覆選擇從另一張表中獲得ID0。當然這並不存在,但我怎麼能告訴Hibernate將0的值視爲與NULL相同 - 在獲取關係時不會循環20次以上,是否存在?

<many-to-one name="device" lazy="false" class="Device" not-null="true" access="field" cascade="none" not-found="ignore"> 
<column name="DEVICEID" default="0" not-null="false"/> 

+0

更好的查詢性能爲什麼默認值是0而不是NULL?另外,FK必須是NULL或目標表中的有效ID。該列實際上是否具有FK常量? – sblundy 2011-01-13 04:07:38

回答

2

我能夠通過創建一個擴展內置Long類型的id-long類型來解決此問題,但如果從SQL返回的ID爲0,則返回null。這使得我們的數據庫中的默認值爲0,同時讓休眠停止進行懶惰提取。

public class IdentifierLongType extends LongType implements IdentifierType { 

@Override 
public Object get(ResultSet rs, String name) throws SQLException { 
    long i = rs.getLong(name); 
    if (i == 0) { 
     return null; 
    } else { 
     return Long.valueOf(i); 
    } 
} 

}

原因執行明確默認爲0是Oracle處理索引和空值奇怪的是,這有明確的價值觀與「其中山坳爲[不]空」

0

我認爲你正在使用原始類型作爲你的目標你的主/外鍵列。如果是,那麼嘗試使用包裝類。因爲基元類型不能將默認值設置爲null。

3

有兩種方法可以做到這一點,可以得到難看的表現方式,以及痛苦和尷尬的方式。

可能醜陋的方式在ToOne結束。使用Hibernate註解這將是:

@Entity 
public class Foo 
{ 
    ... 

    @ManyToOne 
    @JoinColumn(name = "DEVICEID") 
    @NotFound(action = NotFoundAction.IGNORE) 
    private Device device; 

    ... 
} 

不幸的是,這迫使搶佔數據庫命中(無延遲加載),因爲設備可以爲空,如果休眠創建一個懶惰的設備然後選擇「設備== NULL」絕不會真正。

另一種方式涉及創建一個自定義的UserType,它攔截ID 0的請求併爲它們返回null,然後使用@Type將其分配給Device的主鍵。這強制每個使用外鍵的每個人的0〜null解釋進入Device。