Spring JPA @Query注解在SQLite中报错但SQL语句控制台可正常执行
问题分析与解决办法
第一个错误:Query does not return results
这问题根源是:你的@Query写的是UPDATE/DELETE这类无返回结果的操作,但Spring JPA默认会把没加@Modifying的@Query当成查询语句来处理,它会期望得到实体或结果集,自然就报错了。哪怕你的SQL在SQLite控制台能跑,JPA的解析逻辑和原生SQL执行逻辑不一样。
第二个错误:TransactionRequiredException
加@Modifying后,JPA明确这是修改操作,但JPA规定所有更新/删除操作必须在事务上下文里执行,没有事务支撑就会抛出这个异常。
具体修复步骤
- 给你的
@Query方法加上@Modifying注解,明确告知JPA这是修改操作:@Modifying @Query("UPDATE User u SET u.status = ?1 WHERE u.id = ?2") void updateUserStatus(String status, Long id); - 给该方法(或者调用它的Service层方法)加上
@Transactional注解,开启事务:
推荐在Service层加@Transactional @Modifying @Query("UPDATE User u SET u.status = ?1 WHERE u.id = ?2") void updateUserStatus(String status, Long id);@Transactional,更符合分层开发规范,也能统一管理事务范围。
自定义查询的替代方案
如果不想用@Query,还有两种更省心的方式:
- 使用Spring Data JPA的方法命名规则
不用手写SQL,直接按规则定义方法名,JPA会自动生成适配数据库的语句。比如更新用户状态:
这种方式完全不用关心数据库方言差异,适配SQLite毫无问题。@Transactional void updateUserSetStatusById(String status, Long id); - 用EntityManager执行原生SQL
要是非得手写原生SQL,可以注入EntityManager手动执行,记得加事务:@Autowired private EntityManager em; @Transactional public void updateUserStatus(String status, Long id) { String sql = "UPDATE user SET status = ? WHERE id = ?"; em.createNativeQuery(sql) .setParameter(1, status) .setParameter(2, id) .executeUpdate(); }
内容的提问来源于stack exchange,提问作者Grimalkin
相关产品推荐
相关产品推荐

