这是顺序:
- App1:在数据库中保留 ID=1 的实体。没问题。
- App2:外部应用程序删除 ID=1 的同一记录。没问题。
- App1:尝试再次持久化 App2 之前删除的实体,这里抛出一个异常,提示“IntegrityConstraintViolation”,就好像该记录仍在数据库中一样,我插入了两次,但事实并非如此。
事实是,正如我所见,EntityManager 正在使用缓存来验证数据库的完整性。不知怎的,即使在我打电话之后
getEM().getEntityManagerFactory().getCache().evictAll();或者
getEM().clear();
EntityManager 以某种方式将该记录保存在缓存中,而我已经没有关于如何清除该缓存的想法了。我发现的一个解决方法是从 App1 调用:
getEM().remove(entity.class, id);
它也有效地从数据库和 EntityManager 缓存中删除记录。但是,这不是重点,它只是证明它使用缓存进行验证,但主要问题仍然存在,“从另一个应用程序删除记录后,我无法再次持久化记录”。
顺便说一句,我也尝试刷新实体,但也不起作用。它抛出一个异常,表示该实体不受管理。
有人知道如何解决这个问题吗?
最佳答案
App2 是否提交事务?
从数据库中抛出 IntegrityConstraintViolation,因此这意味着旧行仍然存在于数据库中。
打开最好的日志记录并包括两个应用程序的日志和完整的异常堆栈跟踪。
一般来说,转世对象通常不是一个好主意。最好创建一个具有新 id 的新对象,或者至少分离/复制到旧对象。
如果另一个应用程序正在访问同一数据库,您可以考虑禁用缓存,
http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F
否则,如果您只想刷新该对象的缓存,请首先调用 find() 以确保该对象受到管理,然后调用refresh() 将其从共享缓存中删除。 (然后您需要 detach() 它,或者clear() 您的 EntityManager 或创建一个新的)。
关于java - 从数据库中删除记录后,EclipseLink 2.5 在持久实体时仍然抛出 IntegrityConstraintViolation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17307106/