为什么需要在执行修改查询之前清除jpa持久化上下文?

时间:2018-04-10 09:36:07

标签: spring hibernate spring-boot jpa spring-data-jpa

我正在使用Spring Boot 1.5.2.RELEASE和PostgreSQL 9.5数据库。

文件实体:

@Entity
public class File implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String externalUid;
}

文件存储库看起来像:

public interface FileRepository extends JpaRepository<File, Long> {

    @Modifying
    @Query("UPDATE File f SET f.externalUid =:externalUid WHERE f.id =:id")
    void setExternalLink(@Param("id") Long id, @Param("externalUid") String externalId);
}

当我保存新文件(使用flush)并对其执行更新后,从存储库中获取此文件,然后我有过时的实体。但是当我在执行修改查询之前在clear()上执行entityManager [1]时,我得到了更新后的实体:

String externalUid = UUID.randomUUID().toString();

File file = new File();
File savedFile = fileRepository.saveAndFlush(file);

// [1] entityManager.clear();

fileRepository.setExternalLink(savedFile.getId(), externalUid);

File updatedFile = fileRepository.findOne(savedFile.getId());

System.out.print(updatedFile.getExternalUid()); // null

此问题与此问题非常相似:Spring Boot Data JPA - Modifying update query - Refresh persistence context。但在我的情况下,我执行saveAndFlush()而不是save()

在这方面,有人可以解释一下为什么我们需要在执行修改查询之前清除持久性上下文以及为什么存储库会将过时的实体返回给我?

1 个答案:

答案 0 :(得分:0)

重点是hibernate缓存对你做的DML风格查询一无所知。

因此,如果您没有清除缓存并直接在数据库上执行更新,那么相关的缓存对象将会过时。

调用clear()将清空缓存并强制hibernate在后续查询中命中数据库。