使用 Spring JPA “刷新”实体后未反映更改

Posted

技术标签:

【中文标题】使用 Spring JPA “刷新”实体后未反映更改【英文标题】:Changes not reflected after "refreshing" entity with Spring JPA 【发布时间】:2018-05-30 09:01:16 【问题描述】:

我正在努力“刷新”一个看起来像这样的实体 (Foo):

public class Foo 

    //...
    @OneToMany(mappedBy = "fooRef", fetch = FetchType.LAZY)
    private List<Bar> bars;



public class Bar 

    //...
    @Column(name = "FOO_ID")
    private Long fooRef;
    @Column(name = "STATE")
    @Enumerated(EnumType.STRING)
    private State state;

作为Spring JPA doesn't implement the refresh method,我只是再次查询实体。这是它不起作用的代码,我不知道为什么:

for(int i=0; i<MAX_RETRIES; i++) 

    List<Bar> bars = foo.getBars();

    // check bars state

    if(someBarIsBad) 
        try 
            TimeUnit.SECONDS.sleep(delay);
         catch (InterruptedException ignored) 

        
     else 
        break;
    

    foo = fooRepo.findById(fooId);  // "refresh"

目标是继续重试,直到所有柱都达到所需的状态。 我正在做的测试是在循环的最后一条指令处放置一个断点,所以当它中断时,我转到表格并将所有条的状态更改为所需的状态,然后退出循环。问题是新返回的foobars 并没有反映我所做的更改。

我试图消除睡眠,但这不是问题。我认为它必须与映射有关。

【问题讨论】:

我建议问题出在fetch = FetchType.LAZYbars 将在您尝试使用它们时更新。刷新for (Bar bar : foo.getBars()) sout(bar); 后尝试做这样的事情。我希望这会触发延迟初始化。 我测试了删除 LAZY 提取,但结果相同。无论如何,这应该不是问题,因为我正在检索foo 的同一范围内检索barssout 是什么意思?是jpa方法吗? nonono,soutSystem.out.println() 的快捷方式。删除 fetch 不正确,原因是 OneToMany 关系 - 默认 fetch 类型是 LAZY。所以这个删除没有任何改变。尝试将 fetch 从 LAZY 更改为 EAGER。是的,你是对的 - 范围相同,但区别在于直接和间接使用 Bar 实体表。 这真的很奇怪。我尝试了急切的获取,没有。我尝试直接检索barRepo.findByFooRef,但都没有。而且我已经保证通过提交正确地进行更改。 【参考方案1】:

这很可能是因为一切都在单个事务中运行。这会导致 JPA 不会从数据库中重新加载实体,而是返回它在会话中已有的实体。

要么确保您在每次“刷新”时都处于新事务中,要么将实体从会话中逐出,因此它必须再次重新加载。

【讨论】:

有道理。但我不确定我应该如何隔离交易。我把fooRepo.findById(fooId) 包装在一个用@Transactional 注释的方法上。仍然没有给我一个更新的版本。 重要的部分是您在问题中显示的代码没有包装在用@Transactional注释的方法中 我做了,上面的代码和getFoo(ID) 都是事务性的。还是一样的:( 好的,我知道了。我不知道隔离级别。我用 @Transactional(readOnly = true, isolation = Isolation.REPEATABLE_READ) 注释了 getFoo(ID)

以上是关于使用 Spring JPA “刷新”实体后未反映更改的主要内容,如果未能解决你的问题,请参考以下文章

保存后刷新并获取实体(JPA/Spring Data/Hibernate)

直接从querydsl更新数据时如何刷新Spring JPA?

firebase 项目所有者更改后未反映在 Flutter Web 部署上的更改

使用JPA中@Query 注解实现update 操作

合并后未调用的分离实体的生命周期回调

Play 2.4 JPA/Hibernate EntityManager 不刷新到数据库