2013-11-28 49 views
1

我有一個實體(主鍵不是由序列生成)像這樣在Spring Data JPA/EclipseLink的環境:JPA錯誤「無法合併已刪除的實體」試圖刪除並重新插入一行SpringData

@Entity 
@Table(name="MY_ENTITY") 
public class MyEntity implements Serializable { 

    @Id 
    @Column(insertable=true, updatable=true, nullable=false) 
    private String propertyid; 

    \\other columns 
} 

,我試圖從表中刪除一行,並重新插入(具有相同的主鍵)。

我的方法是調用deleteAll()來擦桌子,然後保存()的新實體:

@Transactional 
    public void deleteAndSave(MyEntity entity) { 
     propertyInfoRepository.deleteAll(); 
     propertyInfoRepository.flush(); // <- having it or not, nothing changes 
     propertyInfoRepository.save(entity); 
    }  

,但是這給了我這個錯誤:

Caused by: java.lang.IllegalArgumentException: Cannot merge an entity that has been removed: [email protected] 
at org.eclipse.persistence.internal.sessions.MergeManager.registerObjectForMergeCloneIntoWorkingCopy(MergeManager.java:912) 
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:494) 
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:271) 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3495) 
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:378) 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3455) 
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:486) 
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.merge(EntityManagerImpl.java:463) 
.... 

我在做什麼錯誤? 我不明白爲什麼它試圖合併實體,而不是在刪除後重新插入它。

感謝您的幫助!

回答

1

直接回答你的問題:

的問題是,你試圖挽救實體早已持久化標識,即一個ID,這就是爲什麼你的資料庫將嘗試合併,而不是堅持實體。

如果你看到this question它似乎是在Spring Repository的層次上觸發(至少),所以你可能會考慮覆蓋存儲庫的save方法並測試問題是否仍然存在。

-1

JPA EntityManager記錄每個被管實體的狀態。在你的情況下,你刪除了實體,然後嘗試合併它,這引發了異常。我不知道,如果你的做法是正確的(似乎不可思議刪除,然後合併),因爲你沒有提供的全貌,但你可以嘗試以下方法:

假設em是您的EntityManager和entity你的實體:

em.remove(entity); //This will perform the delete 
MyEntity detachedEntity = em.detach(entity); //Gets a detached copy of the entity, EM will not operated on this unless told to do so (see below) 
detachedEntity.setId(null) // Avoid duplicate key violations; Optional since you are deleting the original entity 
em.persist(detachedEntity); // This will perform the required insert 
+1

我不會嘗試刪除然後合併實體。實體總是一個新的實例(可能具有相同的主鍵),並且此時我調用deleteAndSave方法,但它尚未被管理。 – lincetto