简体   繁体   English

Hibernate 4 composite-id NonUniqueObjectException

[英]Hibernate 4 composite-id NonUniqueObjectException

I have NonUniqueObjectException thrown when upgrading my project from Hibernate 3 to Hibernate 4. I created minimal Hibernate 4 project for testing purposes, and managed to reproduce this exception by: 我将项目从Hibernate 3升级到Hibernate 4时抛出NonUniqueObjectException。我创建了最小的Hibernate 4项目用于测试目的,并设法通过以下方式重现此异常:

  • having entity House, and another entity Door that has a composite id that contains House entity 拥有实体House,另一个实体具有包含House实体的复合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> 

  • and then in the same transaction fetching a House and then fetching Door by composite id with: 然后在同一个事务中获取一个House,然后通过复合id获取Door:

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

Here is the hbm file for House: 这是House的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>

,and the stack trace of the error: ,以及错误的堆栈跟踪:

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)

When reverting this minimal project back to Hibernate 3 the exception is gone, and it all works fine. 当将这个最小的项目还原回Hibernate 3时,异常就消失了,一切正常。

What is the difference in composite-id handling between Hibernate 3 and Hibernate 4? Hibernate 3和Hibernate 4之间的复合id处理有什么区别? How can I make this work in Hibernate 4? 如何在Hibernate 4中完成这项工作?

I recently migrated from hibernate 3 to 4 with two tables with composite ids and related to each other by composite foreign key. 我最近从hibernate 3迁移到了4个带有复合id的表,并且通过复合外键相互关联。 Exactly same configuration worked fine in both versions. 完全相同的配置在两个版本中都运行良好。 So there is no difference as far as basic concepts about composite-id functionality are concerned. 因此,就复合id功能的基本概念而言,没有区别。

You should enable debugging for hibernate APIs ie set debug level for org.hibernate.* to DEBUG in log properties file to see which SQLs are being fired. 您应该为hibernate API启用调试,即将org.hibernate。*的调试级别设置为日志属性文件中的DEBUG,以查看正在触发的SQL。 That will help you see if any additional/unexpected SQLs are being fired by hibernate. 这将帮助您查看hibernate是否正在触发任何其他/意外的SQL。

Make sure your entities, and the objects that make up your composite primary key, have appropriate implementations of hashCode() and equals(). 确保您的实体以及构成复合主键的对象具有hashCode()和equals()的适当实现。 I seem to remember there being some underlying changes in hash-code usage and/or object equality checking between Hibernate 3 and 4. 我似乎记得Hibernate 3和4之间的哈希码使用和/或对象相等性检查存在一些潜在的变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM