You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向Hibernate查询传递方法参数?解决QueryException报错问题

修复Hibernate查询命名参数传递问题

你的问题主要出在两个地方:错误的参数引用语法和不符合JPQL规范的更新语句写法,下面一步步给你解决:

错误原因解析

  1. 你在@Query里用了#{cinema}这种Spring表达式语言(SpEL)的语法,但JPA的@Query注解中,引用命名参数应该使用冒号:,而不是#,这就是报错unexpected char: '#'的直接原因。
  2. JPQL不支持直接把整个实体赋值给查询中的实体变量(也就是set cin = #{cinema}这种写法),必须明确指定要更新的字段。
  3. 另外,@Modifying修饰的update/delete方法,返回值应该是int(表示受影响的行数),而不是实体对象,因为JPQL的更新语句不会返回更新后的实体。

修复方案

方案1:正确使用命名参数,逐个字段更新

修改你的代码,用冒号引用参数,同时明确更新每个字段:

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

@Modifying
@Query("update Cinema cin set cin.name = :cinema.name, cin.address = :cinema.address where cin.id = :cinema.id")
int updateCinema(@Param("cinema") Cinema cinema);
  • 这里:cinema.name会直接引用传入的cinema对象的name属性,Spring Data JPA会自动帮你解析。
  • 返回值int会告诉你这次更新影响了多少条数据,如果你需要获取更新后的实体,可以在调用这个方法后,再调用findById(cinema.getId())来查询。

方案2:用Spring Data JPA自带的save()方法(更简洁)

其实Spring Data JPA已经提供了现成的更新逻辑,如果你不需要自定义JPQL,直接用save()方法即可:

Cinema updateCinema(Cinema cinema);

或者直接复用默认的save()方法:

Cinema save(Cinema cinema);

当你传入的Cinema对象的id已经存在于数据库中时,Spring Data JPA会自动执行update操作,把所有非空字段更新到数据库里;如果id不存在,则执行insert。这种方式不需要写任何@Query注解,非常简洁。

方案3:使用原生SQL更新(不推荐,除非特殊需求)

如果因为某些原因必须用SQL直接更新整个实体,可以用原生SQL,但要注意数据库兼容性:

@Modifying
@Query(value = "UPDATE cinema SET name = :name, address = :address WHERE id = :id", nativeQuery = true)
int updateCinema(@Param("id") Long id, @Param("name") String name, @Param("address") String address);

不过这种方式需要手动传递每个字段,不如方案1或2方便。

额外注意事项

  • 如果你使用@Modifying进行更新/删除操作,别忘了在调用这个方法的业务层方法上加上@Transactional注解,否则会报错。
  • 如果需要在更新后立即获取最新的实体数据,建议在更新后调用查询方法,因为JPQL的update操作不会返回实体。

内容的提问来源于stack exchange,提问作者Nico_99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:04:56