JPA更新查询中Attribute Converter的使用及映射错误解决
问题解决方案
1. 修复映射错误(QuerySyntaxException)
报错核心是自定义查询误用了数据库表名some_entity,JPA默认的@Query使用HQL(Hibernate查询语言),必须引用实体类名而非表名。你的实体类名为SomeEntity,修改查询语句如下:
@Transactional @Modifying @Query("update SomeEntity e set e.spec = :spec where e.name = :name") fun updateReferralProgram(name: String, spec: Spec): Unit
如果非要用原生SQL(不推荐,除非特殊场景),需添加nativeQuery = true参数,同时注意:
- 字段名要对应数据库列名
- 参数需传递Converter转换后的数据库存储类型(比如String),手动调用转换器处理参数:
@Transactional @Modifying @Query(value = "update some_entity e set e.spec = :spec where e.name = :name", nativeQuery = true) fun updateReferralProgram(name: String, spec: String): Unit // 调用时手动转换参数 val dbSpec = SpecConverter().convertToDatabaseColumn(newSpec) repository.updateReferralProgram("L", dbSpec)
2. Attribute Converter在更新查询中的处理
使用HQL(默认@Query)时,JPA会自动应用实体属性上的@Convert转换器:
- 直接传递
Spec类型参数给查询方法即可,Hibernate会自动调用SpecConverter.convertToDatabaseColumn()完成转换 - 查询语句中直接写实体属性名
e.spec,无需关心数据库列名或转换逻辑
额外注意事项
- 确保
SpecConverter正确实现javax.persistence.AttributeConverter<Spec, X>(X为数据库支持的类型,如String、JSONB) - 自定义更新查询必须搭配
@Modifying和@Transactional注解,否则无法执行更新 - 若实体类用
@Table(name = "some_entity")指定了表名,HQL依然要使用实体类名而非表名
内容的提问来源于stack exchange,提问作者Lakshya
相关产品推荐
相关产品推荐

