如何使休眠不保存相等的对象

时间:2012-01-27 13:41:12

标签: hibernate unique equals

我的equals()和hashcode()方法已被正确覆盖。但当 我正在保存相同的对象,它们出现在数据库中。我怎么解决这个问题?我想在数据库中拥有唯一的元素集。 谢谢。

这是映射文件:

<hibernate-mapping>
    <class name="vertical.model.filter.Filter" table="FILTER">
        <id name="id" type="long">
            <generator class="native"/>
        </id>
        <discriminator column="TYPE" type="string"/>
        <subclass name="vertical.impl.filter.AbstractFilter" abstract="true">
            <set name="options" table="FILTER_OPTION" cascade="all">
                <key column="FILTER_ID"/>
                <many-to-many column="OPTION_ID" class="vertical.model.filter.FilterOption"/>
            </set>
            <subclass name="vertical.impl.services.filter.GrfFilter"
                      discriminator-value="rabota">

            </subclass>
        </subclass>

    </class>

</hibernate-mapping>

1 个答案:

答案 0 :(得分:1)

这是一个经典的问题,没有理论上的解决方案,但有实际的解决方法。

让我从article;

开始
  

问题源于虚拟机(VM)中的对象标识与数据库中的对象标识之间的差异。在VM中,您没有获得对象的ID;你只需要直接引用该对象。在幕后,VM确实分配了一个8字节的ID,这是对对象的真正引用。在数据库中持久保存对象时会出现问题。假设您创建一个Person对象并将其保存到数据库(person1)。您在代码中的其他位置读取Person数据并实例化一个新的Person对象(person2)。现在,内存中有两个对象映射到数据库中的同一行。对象引用只能指向一个或另一个,但我们需要一种方法来表明这些实际上是同一个实体。这就是对象身份的来源。

您应该做的很简单,根据实体的业务功能覆盖equals()hashcode()

以下是来自hibernate论坛article;

的建议解决方案
  

分隔对象ID和业务键   为避免此问题,我们建议使用持久化类的“semi”-unique属性来实现equals()(和hashCode())。基本上,您应该将您的数据库标识符视为根本没有业务含义(请记住,无论如何都建议使用代理标识符属性和自动生成的值)。数据库标识符属性应该只是一个对象标识符,基本上只应由Hibernate使用。当然,您也可以使用数据库标识符作为方便的只读句柄,例如在Web应用程序中构建链接。