【问题标题】:Bulk update with HibernateTemplate and IN clause使用 HibernateTemplate 和 IN 子句进行批量更新
【发布时间】:2017-04-14 08:03:22
【问题描述】:

我想使用 Spring 的 HibernateTemplate (Hibernate 5.1) 执行数据库批量更新。

HibernateTemplate 提供以下接口:public int bulkUpdate(String,Object...)

我的查询是UPDATE entity item SET item.attribute.id = ? WHERE item.id in (?.....?)

遇到了很多麻烦,想问一下什么是正确的方法使用HibernateTemplate

  • 上述查询导致弃用警告[DEPRECATION] Encountered positional parameter near line 1, column 172 in HQ
  • 将上述查询替换为 JPA 样式参数 (UPDATE entity item SET item.attribute.id = ?1 WHERE item.id in (?2,?3.....?N)) 会导致 Hibernate 在构建参数元数据时抛出 NullPointerException
  • one of the most authoritative Hibernate sources 所见,命名参数会导致误导性异常

问题是:我如何正确使用 Spring 的 HibernateTemplate 制定批量更新查询?正如 Mykong 正确报道的那样,HibernateTemplate 自动将查询参数设置为从 0 开始,但最终作者让程序使用非位置参数工作,而没有提及(或根本没有)任何警告。

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

    我认为现在推荐的方法是使用Spring Data JPA。有一个入门教程here

    因此,如果您有一个实体,您可以添加一个接口来扩展 SpringDataJpa 中支持的任何存储库接口,并添加一个修改查询。

    public interface CustomerRepository extends CrudRepository<Customer, Long> {
        @Transactional
        @Modifying
        @Query("update Customer c set c.firstName = ?1 where c.id = ?2")
        int updateNameById(String nameToUpdate, long id);
        @Transactional
        @Modifying
        @Query("update Customer c set c.firstName = ?1 where c.id in (?2)")
        int updateNameByIds(String nameToUpdate, List<Long> ids);
    }
    

    然后 Spring 将实现该方法,您可以将其用作:

    customerRepo.updateNameByIds("newName", Arrays.asList(cust.getId())); 
    

    这将生成以下sql:

    update customer set first_name=? where id in (?)
    

    Here是我用来测试的项目

    【讨论】:

    • 感谢您指出 Spring JPA。不幸的是,我不确定我们能否很快在我们的架构中实现这一点(我正在开发的产品基于公司维护的中间件,该中间件在所有开发人员之间共享)。我确实会与团队讨论这个问题,但现在我需要找到解决方案。该查询目前带有警告,因此我没有被阻止。
    • @usr-local-ΕΨΗΕΛΩΝ 或许您可以访问 entityManager / session 并手动执行更新语句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2011-01-21
    • 2012-06-29
    • 1970-01-01
    • 2013-12-07
    • 2012-08-23
    • 1970-01-01
    相关资源
    最近更新 更多