如何刪除detached instance?

http://blog.csdn.net/MyJSF/archive/2007/12/01/1910491.aspx

應用實例環境:Spring jpa hibernate3
常用數據庫表的刪除辦法,一般都會在DAO類中提供delete.如下例:
public class UnitDAO implements IUnitDAO {
        private EntityManager entityManager;
       
        @PersistenceContext
        public void setEntityManager(EntityManager entityManager) {
                this.entityManager = entityManager;
        }
       
        private EntityManager getEntityManager() {
                return this.entityManager;
        }
       
        public void delete(Unit persistentInstance) {
                try {
                        getEntityManager().remove(persistentInstance);
                } catch (RuntimeException re) {
                        throw re;
                }
        }

        public List<Unit> findAll() {
                try {
                        String queryString = "select model from Unit model";
                        return getEntityManager().createQuery(queryString).getResultList();
                } catch (RuntimeException re) {
                        throw re;
                }
        }
}
看上去,沒有任何問題,這也是在MyEclipse中自動產生的代碼。但是,在實際運行過程中,界面會調用findAll()獲得全部的unit記錄顯示在界面層,根據業務需求,用戶選擇一個unit進行刪除,當調用delete方法時,出現異常:
        java.lang.IllegalArgumentException: Removing a detached instance com.gotop.rbac.model.Unit#1
   意思就是說,在刪除一個detached instance出錯。

  •     解決辦法:

看看Hibernate是如何處理對象的.Chapter 10. Working with objects. http://www.hibernate.org/hib_docs/reference/en/html/objectstate.html
    說的很清楚。Hibernate object states有三種狀態:Transient、Persistent、Detached。關於Detached,是這麼說的:
        Detached - a detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the modifications) persistent again.
        一個detached instance是一個已經持久化的對象,但是它的Session已經關閉了,它的引用依然有效,當然,detached instance可能被修改。detached instance能夠在以後可以重新附屬到一個新的Session,使之能重新序列化。
   
        好了,找到解決辦法了,在刪除之前把這個Detached instance綁定到當前的Sesssion,在用當前Sesssion刪除此instance。getEntityManager()提供merge方法實現。
修改後的delete代碼:
        public void delete(Unit persistentInstance) {
                try {
                        getEntityManager().remove(getEntityManager().merge(persistentInstance));
                } catch (RuntimeException re) {
                        throw re;
                }
        }
       千萬不要寫成:
        try {
                getEntityManager().merge(persistentInstance);
                getEntityManager().remove(persistentInstance);
        }              
       執行完merge後persistentInstance還是detached, merge後返回的新對象纔是允許刪除的。  

發佈了9 篇原創文章 · 獲贊 1 · 訪問量 2749
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章