当前位置: 首页 > 知识库问答 >
问题:

Spring Boot Data JPA-修改更新查询-刷新持久性上下文

公孙弘图
2023-03-14

当使用修改查询时,我有一个问题,EntityManager在查询执行后包含过时的实体。

public interface EmailRepository extends JpaRepository<Email, Long> {

    @Transactional
    @Modifying
    @Query("update Email e set e.active = false where e.active = true and e.expire <= NOW()")
    Integer deactivateByExpired();

}

假设我们在DB中有电子邮件[ID=1,active=true,expire=2015/01/01]。

执行后:

emailRepository.save(email);
emailRepository.deactivateByExpired();
System.out.println(emailRepository.findOne(1L).isActive()); // prints true!! it should print false
public interface EmailRepository extends JpaRepository<Email, Long> {

    @Transactional
    @Modifying(clearAutomatically = true)
    @Query("update Email e set e.active = false where e.active = true and e.expire <= NOW()")
    Integer deactivateByExpired();

}
public interface EmailRepository extends JpaRepository<Email, Long>, EmailRepositoryCustom {

}

public interface EmailRepositoryCustom {

    Integer deactivateByExpired();

}

public class EmailRepositoryImpl implements EmailRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    @Override
    public Integer deactivateByExpired() {
        String hsql = "update Email e set e.active = false where e.active = true and e.expire <= NOW()";
        Query query = entityManager.createQuery(hsql);
        entityManager.flush();
        Integer result = query.executeUpdate();
        entityManager.clear();
        return result;
    }

}
@Modifying(flushAutomatically = true, clearAutomatically = true)

共有1个答案

赵钊
2023-03-14

我知道这不是直接回答您的问题,因为您已经构建了一个修复程序,并在GitHub上启动了拉请求。谢谢你这么做!

但我想解释一下您可以使用的JPA方式。因此您希望更改匹配特定条件的所有实体并更新每个实体的值。通常的方法只是加载所有需要的实体:

@Query("SELECT * FROM Email e where e.active = true and e.expire <= NOW()")
List<Email> findExpired();

然后迭代它们并更新值:

for (Email email : findExpired()) {
  email.setActive(false);
}
 类似资料:
  • 如果一次调用<code>会话。保存(customerObject)则不需要插入客户…查询数据库。Hibernate将设置id属性(“序列”或“增量”生成器),并将实体绑定到持久性上下文。当<code>事务时,持久性上下文与数据库同步。调用commit() Q:Hibernate将在哪里设置id属性 Q:在与db同步之前,持久性上下文缓存sql查询是否会插入到customer…中?我的意思是,何时生

  • 我需要从文件中删除封面 调试时,元素已正确删除,但输出封面上的元素仍在此处。 有没有更新/刷新文档xml的方法,即使更改是从低级别发生的,我们如何刷新文档以保持更新

  • 我正在使用Spring Boot 1.5.2。发布和一个PostgreSQL 9.5数据库。 文件实体: 文件存储库看起来像: 当我保存新文件(使用flush)并对其执行更新,然后从存储库获取该文件后,我就有了过时的实体。但是,当我在执行修改查询之前在上执行[1]时,我会得到更新的实体: 这个问题与这个问题非常相似:Spring Boot数据JPA-修改更新查询-刷新持久性上下文。但在我的例子中,

  • 我试图根据用户从UI传递的Id更新表。 问题陈述示例:当用户将Id发送为1时,表应该只更新一行,并使用其他几个参数,如lastModifiedBy和deleted,当我的代码更新表中的所有行时, orm.xml JPA存储库: 服务类别 如果表已经有多个条目,并且我正在尝试更新第一行,那么rest将修改所有行, 例如,对于输入1,只有id=1的一列应该得到modify,但是query也在修改行2、

  • 在Spring声明性事务管理中,当您试图持久化数据库中已经存在的某个实体时,您只能在Spring事务提交期间获得DataIntegrityViolationException。因此,此方法不起作用,此处不会捕获大括号中的异常: 仅在结束时: 我发现了几个解决方法: 不使用@事务 使用冲洗 调用服务时捕获异常 在持久化之前查找 现在我在考虑em.flush和em.find(在坚持之前)。哪种方法更好

  • 2.19 刷新状态查询 2.19.1 描述 返回刷新进度 2.19.2 请求地址 地址: https://api.bokecs.com/queryrefresh/{package_id} 2.19.3 请求方式 GET 2.19.4 请求参数 参数名称 是否必须 参数描述 package_id 是 刷新接口中code为200时返回的message 2.19.5 请求格式 json 2.19.6 举