解决JPA / Hibernate EntityNotFoundException

时间:2013-05-13 05:39:48

标签: java hibernate jpa

我遇到了一个非常奇怪的情况。当我尝试删除一组实体&之后立即尝试添加另一组实体,这些实体可能会或可能不会再次具有相同的元素,我似乎得到了以下异常。不需要整个堆栈跟踪,因为它没有多说。

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对象时, oldEntities newEntities < / strong>列表。

我已经尝试了很多东西来完成这项工作,但没有任何东西可以帮助我克服这个问题。添加FetchType.EAGER&amp; CascaseType.ALL, CascaseType.PERSIST也没有用。 jpa EntityManager似乎也没有commit()方法,我可以在delete()&amp;在store()方法之前。我尝试将store()persist()互换(虽然商店内部调用了persist())!

注意: - 要求是删除旧列表并插入新列表,因为比较元素并且仅添加新元素是繁琐的(有时列表可能非常大)。

2 个答案:

答案 0 :(得分:2)

我认为异常很明显:你告诉会话删除实体X并同时存储实体X.现在可怜的东西很混乱,不知道该怎么做。

在保留新/旧/已删除实体之前,可以通过Session.flush()执行commit

编辑:

如果这不起作用,则需要在新会话中执行插入操作。问题可能仍然是,您没有临时实体,但实际上已删除了一个实体。因此,您可能必须将所有数据复制到新实例中。

答案 1 :(得分:0)

我已经找到了解决方法。我使用flushAndClear()方法而不是flush()方法。

似乎flush()仅将持久性缓存与数据库同步,但没有清除它。

另一方面,

flushAndClear()执行所有待处理操作,然后清除外翻。

从删除方法的org.crank.crud.GenericDao<T, PK extends Serializable>源代码中的java doc引用,

  

从数据库中的持久存储中删除对象。从此   使用PK做删除有可能是实体管理器   如果删除对象,则可能会处于不一致状态   id 1但该对象仍在实体管理器缓存中。

     

你可以做两件事,把你所有的PK删除放在一起,然后再打电话   flushAndClear完成后,或者你只需​​调用delete方法   不会遇到这个问题的实体。

我尝试了使用flushAndClear()方法的第一个选项,它按预期工作。