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

如何更新Spring数据JPA@modifying@query查询中的JPA/hibernate@version字段?

茅曾琪
2023-03-14

为了测试@version注释,我使用以下设置来管理持久性:

  • Spring Boot Starter 1.5.3.发布
  • Hibernate5.2.10.final
  • Spring Data Envers 1.1.3.Release->Spring Data JPA 1.11.3.Release

测试的数据库

  • H2
  • PostgreSQL
  • Mariadb
  • 甲骨文

实体正在使用一个@version注释字段,该字段将在更新时递增。一个示例实体如下所示:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

@Entity
@Table(name = "\"users\"")
public class User {

    @Id
    private Long id;

    private boolean active;

    @Version
    @Column(nullable = false)
    private long version = 0L;

    // getters/setters (not shown)

}

基于Spring Data JPA的UserRepository提供了CRUD查询之外的自定义修改查询:

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {

    @Modifying
    @Query("UPDATE User u SET u.active = false WHERE u.id = ?1")
    void deactivate(Long id);

    @Modifying
    @Query("UPDATE User u SET u.active = false WHERE u.id IN :ids")
    void deactivateAll(@Param("ids") Long... ids);

    @Modifying
    @Query("UPDATE User u SET u.active = false WHERE u.id IN :ids")
    void deactivateAll(@Param("ids") Iterable<Long> ids);

}

由于版本字段不会为JPQL/HQL查询自动增加,因此必须通过相应地调整自定义查询手动完成。

@Modifying
@Query("UPDATE VERSIONED User u SET u.active = false WHERE u.id = ?1")
void deactivate(Long id);

所生成的SQL对所测试的数据库无效,导致如下所示的错误(模式名为TEST):

找不到表“user0_”;SQL语句:update“test”.“users”set user0_.“version”=user0_.“version”+1,“active”=0其中(“id”)(从“ht_users”中选择“id”)[42102-194]

那么,如何更新Spring数据JPA@modifying@query查询中的JPA/hibernate@version字段呢?

共有1个答案

红朝
2023-03-14

可以将u.version=u.version+1添加到查询中。更新后的@querys如下所示:

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {

    @Modifying
    @Query("UPDATE User u SET u.version=u.version+1, u.active = false WHERE u.id = ?1")
    void deactivate(Long id);

    @Modifying
    @Query("UPDATE User u SET u.version=u.version+1, u.active = false WHERE u.id IN :ids")
    void deactivateAll(@Param("ids") Long... ids);

    @Modifying
    @Query("UPDATE User u SET u.version=u.version+1, u.active = false WHERE u.id IN :ids")
    void deactivateAll(@Param("ids") Iterable<Long> ids);

}

使用这个可能会有一些警告。例如。使用optimisticlockException时,这显然不会像EntityManager发布的更新那样失败(如本文所述)。

 类似资料:
  • 问题内容: 我已配置并运行spring-data和hibernate。我可以使用spring- data保存记录,但是由于某些原因,我无法运行查询来更新表中的所有布尔字段。 我尝试了这个: 我也试过这个: 参数除法和节将实现,但表上未更改。 PS我也正在使用MySQL数据库。 问题答案: 我正在使用Spring 3.1和Spring JPA数据。我有一个类似的问题。尝试在1个查询中更新多个记录时,

  • 我已经配置并运行了spring数据和hibernate。我可以使用spring数据保存记录,但由于某些原因,我无法运行将更新表中所有布尔字段的查询。 我试过这个: 我也试过: 参数的划分和部分正在实现,但表上没有变化。 p、 我也在使用mysql数据库。

  • 和 和 我的存储库:

  • 使用spring-boot-starter-data-jpa(版本2.0.4.release)和PostgreSQL(版本9.5.10),我一直得到psqlexception:查询没有返回任何结果,尽管我确实使用了(这里很多人建议的)。按照一些人的建议添加也没有起到什么作用。分析StackTrace可以看到调用了,而应该调用。我能做什么? 编辑:添加完整堆栈-跟踪:

  • 我在这个表上有一个关于hibernate的更新查询 在OrderEntity上,当我有机器名时,我与另一个表有另一个关系。 在JPA存储库中,我有一个查询。基本上,首先我按机器和状态搜索,然后我想更新旧状态以输入状态字段的当前值,然后输入状态以输入新状态。就是这样: 现在我有这个错误

  • 我有3个实体在我的数据库。实体A具有主密钥PK-A,实体B具有主密钥PK-B,实体C具有主密钥PK-C。 实体A与实体B具有1对多关系,实体B与实体C具有1对多关系 我想在Spring Data JPA中基于PK-A(实际上是实体B中的外键)查询实体C。有可能吗? 但这行不通。还有什么建议我可以试试吗?