JPA遇上Lombook的大坑—@Version乐观锁不起作用

2019-11-05更新
最新发现,不是Lombook的锅,但是Lombook也跑不掉责任

以下常见做法:

  • 如果使用了Lombook,就会用Lombook的注解,而不是显式的写出getter和setter方法;因为没有getter和setter方法,jpa的其他注解比如@Column就会加在属性上;
  • 一般项目都有个BaseEntity,里面放了id等公共属性;BaseEntity一般不会用Lombook,公共属性的注解加在了getter方法上,比较符合java面向对象的封装性(让jpa通过get方法访问属性,而不是直接访问私有属性);

注解不起作用的真正原因:
BaseEntity的注解放在哪里,子类的注解也必须放在那里,否则失效(即统一放在属性上,或统一放在getter方法上)。更进一步,如果将BaseEntity的注解同时放在属性上和get方法上,相当于值在get方法上设置注解。

参考:

  • https://segmentfault.com/q/1010000010910022/a-1020000010920576
  • https://www.cnblogs.com/sxdcgaq8080/p/7884477.html
  • https://blog.csdn.net/gaohe7091/article/details/63253386

  某业务需要使用到乐观锁,加了一个version字段,一般使用MyBatis就用sql语句自己去维护version了,但是项目使用的是Spring Data JPA,写hql语句不是很方便,所以用了@Version注解。
  @Version注解在你使用jpa的save()、savaAll()等方法时,会自动对version这个字段作为乐观锁执行必要的操作,失败则会抛出乐观锁异常ObjectOptimisticLockingFailureException挺方便的;但是对于使用@Query注解自己写hql语句的方法并不生效,需要像使用MyBatis那样自己去写,例如:

@Modify
@Query("update ClassName beanName set beanName.aaa = :newAaa, beanName.version = beanName.version+1 where beanName.version = :version")
int updateClassName(@Param("newAaa") String newAaa, @Param("version") Long version)

其中ClassName和beanName分别代表要修改的实体类名称和对象名称。需要自己在hql语句中判断version有没有被改动以及version加1。返回值如果是0,代表修改不成功;需要自己去判断是否为0,然后为0则抛出乐观锁的异常。
  本以为加个注解多简单的事,竟然不起作用?jpa配置改为show_sql: true,即在控制台显示hql语句,发现自动生成的hql语句里没有where version=?的判断条件。说明@Version注解被没有被识别到。
  各种去搜@version注解的正确用法,发现并没有什么特殊配置需求;以及搜索@Version注解不起作用,只能搜到一个回答

引进的类错误
import org.springframework.data.annotation.Version 
改为import javax.persistence.Version

明显不是我遇到的问题。

  自己新建了一个工程去测试,发现没有任何问题,@version注解是起作用的。想想两个工程的区别,是因为项目使用了Lombook
  一通测试,结果如下:

  • 使用Lombook的@Data注解,自动生成getter和setter方法,@Version注解加在version变量上,不生效;
  • 使用Lombook的@Data注解,手动加上version字段的getter和setter方法,@Version注解加在version变量上,不生效;
  • 使用Lombook的@Data注解,手动加上version字段的getter和setter方法,@Version注解加在version的getter方法上,生效;
  • 不使用Lombook的@Data注解,手动生成getter和setter方法,@Version注解加在version变量上和加在version的getter方法上,都生效。

  就是Lombook的锅。
  就是Lombook的锅。
  就是Lombook的锅。
为什么呢?

你可能感兴趣的:(JPA遇上Lombook的大坑—@Version乐观锁不起作用)