我正在使用JPA进行数据持久化。
我无法解释程序中的行为。
我有一个实体A
,其中有另一个实体B
作为其成员。在我的代码中,我创建了A
的新实例并设置了B
的实例(已获取)来自数据库)A
,然后使用A
保存EntityManager
。我正在使用容器管理事务,因此所有事务都应该在方法结束时提交。
在同样的方法中,在持久化A
之后,我尝试获取类C
的实体。 C
与A
一样,B
为其成员。我使用JQPL查询来获取C
的id为B
的实例,我之前与A
的实例相关联。
问题是,在获取C
时,JPA也在执行SQL查询以保存A
。我希望在交易结束时(即方法结束时)发生这种情况。
但是当我尝试获取C
时它就会发生。如果我不提取C
,则在方法结束时会发出用于保存A
的SQL查询。
这种行为的原因是什么?
答案 0 :(得分:0)
原因是数据库隔离级别。它默认是read_commited。 阅读更多关于隔离级别的信息: https://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Read_committed
所以为了不破坏这种隔离,JPA必须在缓冲区中执行事务中所有数据都已到达数据库的所有SQL语句。
答案 1 :(得分:0)
如果查询结果可能与当前持久上下文状态不一致,JPA提供程序需要在查询执行之前刷新持久性上下文。
您可以为所需(或所有)会话设置flush mode至COMMIT
。如果查询依赖于脏持久性上下文状态,请记住手动刷新会话。默认刷新模式为AUTO
,这意味着可以在查询执行之前刷新持久性上下文。