Postgres JSONB类型JPA查询含@符号报错的解决方法
解决JPA执行PostgreSQL jsonb包含查询时@符号报错的问题
JPQL本身不支持PostgreSQL特有的@> jsonb包含操作符,直接编写会触发语法解析错误,以下是两种可行的解决方式:
方案1:使用原生SQL查询
通过启用nativeQuery=true,让JPA直接执行PostgreSQL原生SQL,跳过JPQL的语法校验,即可正常使用@>操作符。
修改后的Repository代码:
@Repository public interface QuestionnaireRepository extends JpaRepository<Questionnaire, Long> { @Query(value = "SELECT * FROM questionnaire WHERE questionnaire @> ?1", nativeQuery = true) List<Questionnaire> findByJsonFilter(String json); }
注意:移除原语句中多余的=号,PostgreSQL的@>操作符本身用于判断jsonb包含关系,无需额外等号。调用时传入合法的JSON字符串即可,例如"{\"company\": \"Magnafone\"}"。
方案2:通过JPQL的FUNCTION调用原生函数
JPQL支持用FUNCTION语法调用数据库原生函数,PostgreSQL的jsonb_contains函数等价于@>操作符,用它可以避开JPQL对@符号的解析问题。
修改后的Repository代码:
@Repository public interface QuestionnaireRepository extends JpaRepository<Questionnaire, Long> { @Query("SELECT u FROM Questionnaire u WHERE FUNCTION('jsonb_contains', u.questionnaire, ?1) = true") List<Questionnaire> findFromQuestionnaireQuery(String json); }
这种方式保留了JPQL的风格,同时能利用PostgreSQL的jsonb特性,参数同样需要传入格式正确的JSON字符串。
额外注意事项
确保实体类中对应字段正确映射为PostgreSQL的jsonb类型:
@Entity @Table(name = "questionnaire") public class Questionnaire { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(columnDefinition = "jsonb") private String questionnaire; // 也可使用JsonNode类型,配合Jackson转换器处理 // getter、setter方法 }
内容的提问来源于stack exchange,提问作者Malinda Peiris
相关产品推荐
相关产品推荐

