2014-11-25 109 views
4

我NonUniqueObjectException拋出升級從休眠3我的項目時,休眠4. 我創建最小休眠4項目用於測試目的,並設法重現此異常:休眠4複合-ID NonUniqueObjectException

  • 有實體樓,並具有包含衆議院實體的複合ID的另一個實體門

    <class dynamic-insert="true" dynamic-update="true" name="entity.Door" select-before-update="true" table="DOOR"> 
    <composite-id name="id" class="DoorHousePK"> 
        <key-many-to-one class="entity.House" column="HOUSEID" name="house"/> 
        <key-property column="DOORID" name="doorId" type="string"/> 
    </composite-id> 
    

  • ,然後在同一個事務獲取一個房子,然後用取門由複合ID:

(Door)session.get(Door.class, doorHousePK)

這裏是家的HBM文件:

<class dynamic-insert="true" dynamic-update="true" name="entity.House" select-before-update="true" table="HOUSE"> 
     <id column="ID" name="id" type="int"/> 
     <property column="squarefeet" name="squareFeet" not-null="false" type="int"/> 
     <property column="address" length="255" name="address" not-null="false" type="string"/> 
     <property column="color" length="32" name="color" not-null="false" type="string"/> 
     <property column="description" name="description" not-null="false" type="materialized_clob"/> 
    </class> 

,和堆棧跟蹤的錯誤:

INFO: HHH000327: Error performing load command : org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [entity.House#1] 
Exception in thread "main" org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [entity.House#1] 
    at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:617) 
    at org.hibernate.event.internal.AbstractReassociateEventListener.reassociate(AbstractReassociateEventListener.java:74) 
    at org.hibernate.event.internal.DefaultLockEventListener.onLock(DefaultLockEventListener.java:95) 
    at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:774) 
    at org.hibernate.internal.SessionImpl.fireLock(SessionImpl.java:767) 
    at org.hibernate.internal.SessionImpl.access$1800(SessionImpl.java:176) 
    at org.hibernate.internal.SessionImpl$LockRequestImpl.lock(SessionImpl.java:2491) 
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.addKeyManyToOnesToSession(EntityLoadQueryDetails.java:263) 
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:247) 
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:129) 
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138) 
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102) 
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186) 
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126) 
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468) 
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213) 
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275) 
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151) 
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070) 
    at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:176) 
    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2551) 
    at org.hibernate.internal.SessionImpl.get(SessionImpl.java:955) 

當這個最小的項目恢復到休眠3時,異常是g一個,而且一切正常。

Hibernate 3和Hibernate 4之間的複合id處理有什麼區別? 如何在Hibernate 4中完成這項工作?

回答

0

我最近從休眠3遷移到4與兩個表複合ID和相互關聯的複合外鍵。兩個版本的配置完全相同。所以就複合id功能的基本概念而言,沒有區別。

您應該啓用對hibernate API的調試,即將org.hibernate。*的調試級別設置爲日誌屬性文件中的DEBUG以查看哪些SQL正在被觸發。這將幫助您查看是否有任何額外的/意外的SQL被hibernate激發。

+0

我附加了最小項目到這個票和問題是在這個最小的項目中再現時切換Hibernate 3和4.這是min項目連接的票證https://hibernate.atlassian.net/browse/HHH-9521。 – jovankricka 2014-12-01 10:08:41

+0

我看着你的代碼。您使用相同的ID加載父對象兩次。一旦在Hib4Min.java主要方法中,然後在ChildService的reproduceNonUniqueObjectException方法中。你可以安全地註釋掉後面的調用(ChildService.java中的一個調用),因爲你不需要它。如果你需要父對象,你可以從ChildParentPK的getParent方法中獲取它。一旦你註釋掉這個調用,你的代碼就可以正常運行。我還沒有嘗試在休眠3運行。 – Jitesh 2014-12-01 19:30:50

+0

其實是什麼導致問題是ChildService的重現NononiqueObjectException中的兩個調用: - getParentById和 - getChildById。 getParentById的第一個調用與問題無關。問題是這些其他兩個調用都在同一個事務中。 我的項目代碼中有類似的情況,我們在這裏獲取父對象,然後在同一事務中獲取子對象。 這是在Hibernate 3中工作,而不是在Hibernate 4中工作。 所以我想知道爲什麼這在Hibernate 3中工作,並在Hibernate 4中拋出異常。 – jovankricka 2014-12-02 09:21:54

0

確保您的實體以及構成組合主鍵的對象具有相應的hashCode()和equals()實現。我似乎記得在Hibernate 3和4之間哈希代碼使用和/或對象相等性檢查存在一些根本性的變化。