2012-01-27 36 views
1

我的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> 
+0

儘管Hibernate知道你的對象是否都有相同的主鍵? – dasblinkenlight 2012-01-27 13:45:12

+0

我有大的繼承樹,但所有的子類映射到一個接口,至少有ID – 2012-01-27 13:48:16

+0

如果需要更多的信息,我會發布它 – 2012-01-27 13:51:01

回答

1

這是一個沒有理論解一個經典的問題,但也有解決它的實用方法。

讓我從article;

該問題源於虛擬機(VM)中的對象標識與數據庫中的對象標識之間的差異。在虛擬機中,你不會得到一個對象的ID;您只需保持對該對象的直接引用。在幕後,虛擬機確實分配了一個八字節的ID,這就是對一個對象的引用。當您在數據庫中保留對象時,問題就會開始。假設您創建一個Person對象並將其保存到數據庫(person1)。在代碼中的其他位置,您可以在人員數據中​​讀取並實例化新的Person對象(person2)。您現在在內存中有兩個映射到數據庫中同一行的對象。對象引用只能指向一個或另一個,但我們需要一種方式來表明這些實際上是相同的實體。這就是對象的身份進來。

你應該做的很簡單,根據實體的業務功能覆蓋equals()hashcode()

這裏是冬眠論壇article的建議解決方案;

分離對象ID和業務關鍵 爲了避免這個問題,我們建議您使用持久化類的「半成品」 - 獨特的屬性,以實現equals()(和hashCode())。基本上你應該認爲你的數據庫標識符根本沒有商業意義(記住,無論如何推薦代理標識符屬性和自動生成的值)。數據庫標識符屬性應該只是一個對象標識符,基本上只應該由Hibernate使用。當然,您也可以使用數據庫標識符作爲方便的只讀句柄,例如在Web應用程序中構建鏈接。