jpa刪除根據對象刪除失敗,報Removing a detached instance 錯


引用:https://blog.csdn.net/zhanggnol/article/details/6307936

 

常用數據庫表的刪除辦法,一般都會在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后返回的新對象才是允許刪除的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM