传递给分离的实体持久化

时间:2014-10-15 08:34:05

标签: java hibernate jpa

CacheId aci = new CacheId();
aci.setId(cacheObject.getId());
aci.setSequence(cacheObject.getSequence());
Cache persisted = em.find(Cache.class, aci);
if (persisted == null){
    System.out.println("========== PERSISTING");
    em.persist(cacheObject);
}else{
    System.out.println("========== MERGING");
    em.merge(cacheObject);
}

在运行我的项目时,另一个实例删除具有当前CacheId的条目。现在我需要做的是将新值设置为具有相同缓存ID的数据库。但是当我执行em.find()时,这不会返回null。 (但是在数据库条目中已经删除。所以这最终会调用merge。并且尝试更新1但是更新了0 ...

但是如果我停止检查搜索并且呼叫持续存在,那么我得到"分离的实体传递给持续#34;。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您遇到并发访问问题,答案是锁定。如果在应用程序中使用乐观锁定,只需捕获异常并重试(有限数量或多次)。

您还可以使用:

来使用悲观锁定模式
Cache persisted = em.find(Cache.class, aci, LockModeType.PESSIMISTIC_WRITE);

(或LockModeType.PESSIMISTIC_READ)。锁定是从数据库中立即获得的,即如果数据已被删除,您将立即知道。一旦获得锁定,就不允许其他任何交易将其删除。

唯一剩下的竞争条件是如果两个事务尝试创建相同的数据。

但请注意:应用程序应尽快提交以释放锁定,以避免潜在的死锁或不必要的其他事务阻塞。