2013-05-13 76 views
0

我遇到了一個非常奇怪的情況。當我嘗試在後面立即刪除一組實體&時嘗試添加另一組實體,這些實體可能也可能不再有相同的元素,我似乎正在獲得以下例外。整個堆棧跟蹤不是必需的,因爲它不會說太多。解決JPA/Hibernate EntityNotFoundException

javax.persistence.EntityNotFoundException: deleted entity passed to persist [com.test.MyEntity#<null>] 

爲了讓自己更清楚,讓我給出更詳細的解釋。

這是我的實體。

@Entity 
@Table(name = "MY_ENTITY") 
@SequenceGenerator(name = "my_enty_seq", sequenceName = "MY_ENTITY_SEQ") 
public class MyEntity { 

    private long id; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "my_enty_seq") 
    @Column(name = "ID", unique = true, nullable = false, precision = 12, scale = 0) 
    public long getId() { 
     return this.id; 
    } 

    // Other methods & variables which are not relevant here. 
} 

這是玩實體的類。

public class MyEntityServiceImpl implements MyEntityService { 

    public void updateMyEntities(List<MyEntity> newEntities) { 

     // Delete the Old Items 
     List<MyEntity> oldEntities = myDAO.getAllEntities(); 
     myDAO.delete(oldEntities); // myDAO extends GenericDaoJpaWithoutJpaTemplate, hence, the DELETE is available in it. 

     // Add the New Items 
     myDAO.store(newEntities); // This is where I get the mentioned Exception. 
    } 

    // Other non-relevant stuffs 
} 

從哪裏獲得的store()方法所提到的例外的情況是有一些共同的MyEntity對象,同時存在於oldEntitiesnewEntities名單。

我已經嘗試了很多事情來完成這項工作,但沒有任何東西可以幫助我解決問題。添加FetchType.EAGER & CascaseType.ALL, CascaseType.PERSIST也沒有工作。 jpa EntityManager似乎也沒有commit()方法,我可以在store()方法之前的delete() &之後使用。我試過與交換store()(雖然店內也叫persist())!

注意: -需要刪除舊列表並插入新列表,因爲比較元素並只添加新元素是很繁瑣的(列表可能有時非常龐大)。

回答

0

我已經想出了一個辦法。我用flushAndClear()方法代替flush()方法。

看起來flush()只將持久性緩存與數據庫同步,但沒有清除它。

flushAndClear()另一方面執行所有掛起的操作,然後清除everthing。

從存在於org.crank.crud.GenericDao<T, PK extends Serializable>爲刪除方法的源代碼的Java文檔引用,

刪除從數據庫中的持久存儲器中的對象。由於此 使用PK執行刪除,因此如果刪除對象爲 id 1但實體管理器 可能會處於不一致狀態,但該對象仍在實體管理器緩存中。

你可以做兩件事情,把你所有的PK將刪除在一起,然後調用 flushAndClear完成時,或者你可以調用delete方法與 ,不會存在這個問題的實體。

我試着使用flushAndClear()方法的第一個選項,它按預期工作。

2

這個例外很明顯我想:你告訴會話刪除實體X,同時存儲實體X.現在可憐的東西很困惑,不知道該怎麼做。

在堅持新/舊/刪除實體之前,可能通過commit執行Session.flush()

編輯:

如果不這樣做的伎倆,你需要做插入一個新的會話。問題可能仍然是,你沒有一個短暫的實體,但實際上刪除了一個。因此,您可能必須將所有數據複製到新實例中。

+0

一個提交只是在實際提交事務之前進行刷新。 – 2013-05-13 05:52:47