簡體   English   中英

解決JPA / Hibernate EntityNotFoundException

[英]Resolving the 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.EAGERCascaseType.ALL, CascaseType.PERSIST也無法正常工作。 jpa EntityManager似乎也沒有commit()方法,我可以在delete()之后和store()方法之前使用它。 我嘗試用persist()交換store() (盡管store內部調用persist() )!

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

我認為這個例外非常清楚:你告訴會話刪除實體X並同時存儲實體X.現在可憐的東西很混亂,不知道該怎么做。

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

編輯:

如果這不起作用,則需要在新會話中執行插入操作。 問題可能仍然是,您沒有臨時實體,但實際上已刪除了一個實體。 因此,您可能必須將所有數據復制到新實例中。

我已經找到了辦法。 我使用了flushAndClear()方法而不是flush()方法。

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

flushAndClear()執行所有掛起的操作,然后清除everthing。

org.crank.crud.GenericDao<T, PK extends Serializable>源代碼中的java doc引用org.crank.crud.GenericDao<T, PK extends Serializable> for delete方法,

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

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM