如何判断Spring Data JPA操作是否执行?自定义删除返回布尔值报错如何解决
问题1解答:Spring Data JPA写操作的内部实现
- 你自定义的派生删除方法、加了
@Modifying注解的更新/删除类查询,底层确实是调用JPA规范的Query#executeUpdate()方法执行,该方法原生返回int类型值,代表本次操作影响的数据库行数。你最开始将返回值定义为boolean触发类转换异常,就是因为Spring Data JPA默认不会自动将底层返回的整数转换为布尔值。 - 而JpaRepository自带的
deleteById方法逻辑和自定义派生删除方法不同:它会先根据ID查询对应的实体,如果查询不到直接抛出EmptyResultDataAccessException,查询到实体后调用EntityManager#remove()方法执行删除,全程没有获取受影响行数,所以返回值为void。
问题2解答:void返回值的JPA方法判断执行成功的方案
- 第一种是靠异常判断:JPA的写操作如果执行失败(包括实体不存在、数据库约束冲突、事务异常等场景)都会抛出对应层级的持久化异常,比如
EmptyResultDataAccessException、PersistenceException、DataAccessException等,方法执行过程中没有抛出异常就代表操作成功。 - 第二种是自行调整实现避免使用void方法:就像你现在的改造方式,自定义派生删除方法返回受影响行数,判断返回值>0即代表操作成功,这种方式性能最优,也是工业界常用的实现方案。如果需要直接返回布尔值,也可以在Service层对返回的行数做转换即可。
- 第三种是同事务内二次校验:如果必须使用原生的void返回值方法,可以在同一个事务内执行完删除操作后,调用
existsById方法查询对应ID是否还存在,不存在即可判定删除成功,这种方式会多一次查询请求,适合对性能要求不高的场景。
内容的提问来源于stack exchange,提问作者wick3d
相关产品推荐
相关产品推荐

