2011-06-01 36 views
1

我有型「文件夾」的對象之間一個非常簡單的父 - /子關係,它看起來像這樣:休眠刪除後了Session.update(父)子對象

  • 一個文件夾可以有0-1父文件夾。
  • 一個文件夾可以有0-n個子文件夾 (子文件夾)。

所以,基本上,Java類文件夾的簡化版本是這樣的:

public class Folder{ 
    long id; 
    Set<Folder> childFolders; 
    Folder parentFolder; 
    String path; 

    // Getter, setter and other (for this question) 
    // not relevant properties omitted 

    public boolean equals(Object obj){ 
      if (obj == null) return false; 
      if (obj == this) return true; 
      if (obj instanceof Folder){ 
        Folder folder = (Folder)obj; 
        return folder.getPath().equals(getPath()); 
      } 
      return false; 
    } 

    public int hashCode(){ 
      return getPath().hashCode(); 
    } 

} 

我簡單的測試層次結構是這樣的:

folder1 
    folder2 
- folder3 
    subfolder3-1 

使用Hibernate,我呼籲:

session.update(folder1); 
session.update(folder2); 
session.update(folder3); 

前兩個調用成功。

最後一次對folder3的調用不會引發異常,但它會從folder3的內部set「childFolders」中刪除子文件夾3-1。 這意味着,folder3.childFolders.size() = 0儘管在最後一次更新呼叫之前是1。 重要提示:在數據庫中,文件夾「subfolder3-1」仍然存在!

這怎麼可能?

這裏是我的映射文件:

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
    <class name="test.Folder" table="FOLDERS"> 

     <id name="id" type="long" access="field"> 
      <column name="FOLDER_ID" /> 
      <generator class="native" /> 
     </id>  

     <set name="childFolders" table="FOLDERS" inverse="true" cascade="save-update"> 
      <key column="PARENT_FOLDER_ID"></key> 
      <one-to-many class="test.Folder" /> 
     </set> 

     <many-to-one name="parentFolder" column="PARENT_FOLDER_ID" /> 

     <property name="path" column="FOLDER_PATH" /> 
    </class> 
</hibernate-mapping> 
+0

'test.Folder'中的'equals()'和'hashcode()'方法是什麼樣的? – 2011-06-01 20:34:06

+0

@matt b我在原文中加了兩個方法 – Timo 2011-06-01 21:17:37

回答

0

我增加了一些調試代碼,我終於找到了解決辦法:直接在session.update(folder3)電話之前,我有一個小小的隱藏folder.childFolders.clear()調用這顯然造成了問題,所以這個問題也沒有與Hibernate有關。只是我的愚蠢。 對不起,每個人都很煩惱,並且非常感謝您的幫助!

0

我認爲這個問題是在逆=「true」屬性:inverse屬性不會被保存。

+0

Hm,設置inverse =「false」沒有解決問題。除此之外:調用session.save(folder3)完美地工作。 – Timo 2011-06-01 21:31:41

0

確保您在java世界中正確建立鏈接。

folder3.getChildFolders().add(subfolder3); 
    subfolder3.setParent(folder3); 
    session.persist(folder3); //cascade here will save subfolder3 

Here is the hibernate documentation.

+0

在我調用上面發佈的session.update(..)方法之前,所有文件夾都已經存在了!所以,我在永久性文件夾上調用session.update(..)。爲了將文件夾插入數據庫(第一次),我使用session.save。(folder3)(完美工作)而不是session.persist(folder3)。那是錯的嗎? – Timo 2011-06-01 22:13:03

+0

在最初將文件夾插入到數據庫中的代碼中,是否還要將該文件夾添加到父項(如上面的@zmf所示)? – RMorrisey 2011-06-01 22:26:31

+0

@Rorrisey是的,我喜歡。我還在'session.update(folder3)'調用之前和之後一次打印樹(包括父和父的名稱)。在'session.update(folder3)'之前,'一切都是它應該的(子文件夾3-1有一個id和一個對它的父親的引用)。更新調用後,子文件夾3-1不見了。 – Timo 2011-06-02 00:22:02