java - 为什么没有读取 JPA find() 方法未提交的更改?

标签 java jpa eclipselink wildfly-10

我对 JPA 行为感到困惑,这是我没有想到的(使用 Eclipselink)。

我在 Wildfly 10 (JDK-8) 上运行无状态 session EJB (3.2)。我的方法调用默认封装在事务中。 现在,我的业务方法在读取和更新实体 bean 时无法识别更新 - 特别是实体的版本号。所以我的通话结果是

org.eclipse.persistence.exceptions.OptimisticLockException

我的代码看起来简化如下:

public ItemCollection process(MyData workitem) {

    ....
    // load document from jpa
    persistedDocument = manager.find(Document.class, id);
    logger.info("@version=" + persistedDocument.getVersion()); 
    // prints e.g. 3

    // change some data
    ....
    manager.flush();
    logger.info("@version=" + persistedDocument.getVersion()); 
    // prints e.g. 4

    ....
    // load document from jpa once again
    persistedDocument = manager.find(Document.class, id);

    logger.info("@version=" + persistedDocument.getVersion()); 
    // prints e.g. 3  (!!)

    // change some data
    ....
    manager.flush();
    // Throws OptimisticLockException !!
    // ...Document@1fbf7c8e] cannot be updated because it has changed or been deleted since it was last read

    ...
}

如果我将代码(更改数据并刷新实体 bean)放在用

注释的方法中
@TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW)

一切都按预期进行。

但是为什么我的代码中第二次调用 find() 方法没有读取新的版本号?我期望在flush() 和find() 调用之后出现版本4。

最佳答案

毕竟看起来像是在打电话

manager.clear();

问题解决了。我认为分离对象应该做同样的事情,但在我的例子中,仅调用clear()确实解决了问题。

更多发现:

毕竟,在服务层中调用 detach() 和lush() 方法似乎不是一个好主意。我这样做是因为我想在离开业务方法以将该 id 返回给客户端之前获取实体的新版本 id。在这种情况下,我改变了我的策略,通过分离和刷新我的实体 bean 来删除所有“坏东西”。代码变得更加清晰,代码复杂度大幅降低。

当然,entityManager 现在行为正确。如果我在一个事务中多次查询同一个实体 bean,entityManager 将返回正确的更新版本。

所以我自己的问题的答案是:保留方法flush()和clear(),只要没有充分的理由使用它们。

关于java - 为什么没有读取 JPA find() 方法未提交的更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40317327/

相关文章:

jpa - EclipseLink/JPA @OneToMany 反向指针基数错误

java - 从 logback 或属性文件中隐藏第三方 jar 日志

java - JPA 元模型字段为空

java - "Generate entities from table"(MS Access) 在 Eclipse 中通过 UCanAccess

java - : sequence id using JPA @TableGenerator, @GeneratedValue 与数据库 Auto_Increment 之间有什么区别

java - 我如何让 MOXy 仅在一行上输出以节省空间

java - java中的素数测试

java - 循环数组支持的队列: enqueues at wrong offset after resizing

java - JPA 和服务器时区错误

java - JPA:如果 EntityManager 关闭,为什么加载惰性字段