对于测试@Version注释,我使用以下设置来管理持久性:
测试数据库:
实体正在使用@Version带注释的字段,该字段为incremented on update。一个示例实体看起来像这样:
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)
}
除了CRUD之外,基于Spring Data JPA的UserRepository提供了自定义修改查询:
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查询,因此必须通过相应调整自定义查询来手动手动 。
当尝试使用特定于Hibernate的(符合非JPA标准) VERSIONED 关键字(仅限HQL)来扩展查询时
@Modifying
@Query("UPDATE VERSIONED User u SET u.active = false WHERE u.id = ?1")
void deactivate(Long id);
生成的SQL无效与测试的数据库无关,导致错误看起来像这样(模式名称为TEST):
表&#34; USER0 _&#34;未找到; SQL语句:更新&#34; TEST&#34;。&#34;用户&#34;组 user0 _。&#34; version&#34; = user0 _。&#34; version&#34; +1,&#34; active&#34; = 0 where(&#34; id&#34;)IN (选择&#34; id&#34;来自&#34; HT_users&#34;)[42102-194]
那么,如何更新Spring Data JPA @Modifying @Query查询中的JPA / Hibernate @Version字段?
答案 0 :(得分:1)
您可以添加 u.version=u.version+1
查询。更新后的@Query
看起来像这样:
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);
}
使用此功能可能会有一些警告。例如这显然不会因为EntityManager do(as described here)发出的 OptimisticLockException
更新而失败。
答案 1 :(得分:0)
回答类似的问题here - 尝试在UPDATE关键字后添加VERSIONED关键字:
@Modifying
@Query("UPDATE VERSIONED User...)