2011-09-22 84 views
2

在我的GWT應用程序中,我將一個對象傳遞給服務器以便與Hibernate保持一致。該對象包含另一個對象的列表。列表中的每個元素都包含一個Map,它是另一個Hibernate表。更新包含休眠列表的對象

爲了做到這一點的交易,這是我的理解是,我必須首先:

  1. 進行查找通過 休眠
  2. 獲得來自數據庫的持久化對象修改對象
  3. 更新通過Hibernate的

這裏的對象是我在做什麼一些快速代碼:

public void saveOrUpdateObject(final Foo foo) 
{ 
    Session session = sessionFactory.getCurrentSession(); 
    session.beginTransaction(); 

    Object lookup = myDAO.getObject(foo.getUniqueValue()); 

    if (lookup != null) { 
     lookup.getList().clear(); 
     lookup.addAll(foo.getList()); 

     myDAO.update(lookup); 
    } 
    else { 
     myDAO.save(foo); 
    } 
} 

使用這種方法,我偶爾會屬於HibernateException:

org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: my.Foo.list 

什麼是更新包含使用Hibernate的集合對象的正確方法?

回答

5

問題有其託管和非託管對象的事:

  • 查找是一個管理對象,如lookup.list,一切都在它
  • Foo不是管理對象,無論是在任何的foo.list需要

當你調用lookup.getList().clear(),你是信號對Hibernate在管理列表,一切都將被刪除(由於all-delete-orphan CASC ading)。然而,你然後回來並添加一些東西到那個(託管)列表中,包括一些可能已經存在的東西。 Hibernate會感到困惑並拋出異常。

而不是手動調整管理對象的列表,使用merge(foo)來更新持久實例的狀態與非託管實例。從Hibernate manual

如果存在與當前與會話相關聯的相同標識符的持久化實例,給定對象的狀態複製到持久實例

合併提出搞清楚的責任哪個狀態更新到Hibernate。