为什么我得到一个OptimisticLockException?

时间:2013-07-11 18:25:15

标签: java jpa openjpa

我正在尝试更新实体列表。实际上我必须两次更新每个实体。首先,我需要设置一些状态,然后执行一些操作来生成pdf报告,然后再次更新该实体的状态。而且我得到了这个OptimisticLockException。此表未在系统中的任何其他位置更新。我不知道我做错了什么。

public void procesarImpresiones() {
    Query q = em.createNamedQuery("Gapendte.selectByState");


    for (Object p:q.getResultList()){
        Gapendte pend = (Gapendte) em.merge(p);

        pend.setKy1("2");

        em.flush();

        try{

            //print something to pdf
            ...

            pend.setKy1("9");
        }catch (Exception e) {
            pend.setKy1("7");
        }

        em.flush();
    }    
}

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

flush正在更新数据库中的实体版本。我认为新版本号将被重新加载到当前实例中,但似乎不是。你应该在冲洗后尝试调用em.refresh(pend)

答案 1 :(得分:0)

如果你正在使用连接池和那些东西,你将需要重新配置锁或至少他们的时间。来自JBoos文档: “事务隔离通常通过锁定事务中访问的任何内容来实现。事务锁定有两种不同的方法:悲观锁定和乐观锁定。

悲观锁定的缺点是资源在事务中首次访问时被锁定,直到事务完成为止...... ...使用乐观锁定,当事务首次访问资源时,资源实际上不会被锁定。相反,保存了用悲观锁定方法锁定的资源状态......“

所以你必须配置正确的锁定策略和时间,例如:

    EntityManager em = ...;
    Person person = ...;
    em.lock(person, LockModeType.OPTIMISTIC);

取自java EE 6文档http://docs.oracle.com/javaee/6/tutorial/doc/gkjiu.html

答案 2 :(得分:0)

即使很难我也没有解决方案,我知道这个问题是错误的。由于一些奇怪的编码不兼容性而生成错误。它与锁无关(至少不是直接),但是某些数据存储在我试图更新的@id字段中。