【问题标题】:How to JPA Query for Postgresql array?如何对 Postgresql 数组进行 JPA 查询?
【发布时间】:2020-12-16 13:08:23
【问题描述】:

如何使用 text[] 列查询 Postgresql 表的这个模型:

@TypeDefs({
    @TypeDef(
        name = "string-array", 
        typeClass = StringArrayType.class
    )
})

@Entity
@Table(name = "names")
public class Names implements Serializable
{  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false)
    private Integer id;
    
    @Column(name = "name", nullable = false)
    private String name;
    
    @Type(type = "string-array")
    @Column(name = "tags", columnDefinition = "text[]")
    private String[] tags;
    
    ...
}

这是我尝试的 CrudRepository 查询,但验证失败:

@Query("SELECT t FROM Names t WHERE :tag MEMBER OF t.tags")
Iterable<Names> findByTag(@Param("tag") String tag);

我可以找到有关如何插入、更新和删除 SQL 数组的示例和文档,但找不到有关如何查询它们的示例和文档。

【问题讨论】:

  • 这能回答你的问题吗? Error while mapping postgres arrays in Spring JPA
  • 很遗憾没有。映射工作正常,查询返回数据。问题是在数组中搜索。我猜 MEMBER OF 要求该属性是一个集合。希望 Vlad Mihalcea 出现并用简短的语言向我解释 :)
  • 总有编写原生查询的选项,不受 jpql 等限制。
  • 是的,原生查询是我的后备。还不错,因为几乎只有 Postgresql 支持 SQL 数组。
  • 根据这篇博文,这是行不通的。引用 Vlad 评论:“JPQL 不支持存储多个属性的基本类型。因此,您应该改用 SQL。”。 How to map a PostgreSQL ARRAY to a Java List with JPA and Hibernate 尝试使用原生查询:@Query(value = "SELECT * FROM Names t WHERE :tag = ANY(t.tags)", nativeQuery = true)

标签: postgresql spring-boot hibernate jpa


【解决方案1】:

当我想查询特定参数值(INTEGER)是否包含在数组类型(INTEGER[])列中时,我遇到了同样的问题。

... WHERE :type MEMBER OF (TABLENAME.typeArray)... => 使用 NullPointerException 验证失败

... WHERE :type ANY(TABLENAME.typeArray)... => 验证失败,因为 'TABLENAME' 是一个意外的令牌

...WHERE :type IN (TABLENAME.typeArray)... => 通过验证,但在执行过程中失败,operator does not exist: integer = integer[]

最终对我有用的是Fabricio Colombo 在对上述答案之一的评论中提出的解决方案 - 归功于他,我只是重新发布解决方案以获得更好的可见性,因为我之前也挣扎了一段时间我找到了。

@Query(value = "SELECT * FROM TABLE WHERE :type = ANY(TABLE.ARRAY_COLUMN)", nativeQuery = true)    

【讨论】:

    【解决方案2】:

    试试

    @Query("SELECT t FROM Names t WHERE t.tags  @> CAST(?1 AS text[])")
    List<Names> findByTag(String tag);
    

    如果这不起作用,则共享异常。

    【讨论】:

    • org.hibernate.QueryException: unexpected char: '@' [SELECT t FROM Names t WHERE t.tags @> CAST(:tag AS text[])]
    • 此表示法适用于 eclipselink。您可以使用本地查询来进行休眠。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多