【问题标题】:HQL - Check if an Array contains a valueHQL - 检查数组是否包含值
【发布时间】:2021-07-15 10:55:35
【问题描述】:

我的第一个实体类中有一个数组字段,如下所示:

class Entity1{
       private Integer col1;
       private String col2;
       private Integer[] col3Arr;
}

我有另一个实体类如下:

class Entity2{
       private Integer col1;
       private String col2;
       private Integer col3;
}

我通过加入多个其他实体来获取记录,如果 col3Arr 包含来自实体 2 的值 col3,我必须同时加入 Entity1

使用 PSQL,我可以通过以下语句轻松实现这一目标

//Other part of query
join Entity2 e2 on (//conditions from other joined tables//)
join Entity1 e1 on e2.col3=ANY(e1.col3Arr)

什么是 ANY 的 HQL 等价物? 或者HQL中是否有其他方法可以检查数组是否包含特定值?

【问题讨论】:

    标签: postgresql hibernate spring-data-jpa hql hibernate-mapping


    【解决方案1】:

    为了映射数组,您需要一个自定义类型。您可以为此使用休眠类型项目:https://vladmihalcea.com/how-to-map-java-and-sql-arrays-with-jpa-and-hibernate/

    您尝试使用e2.col3 = FUNCTION('ANY', e1.col3Arr) 了吗?如果这不起作用,我建议您创建一个自定义 SQLFunction 来呈现您想要的 SQL,例如

    public class ArrayAny implements SQLFunction {
    
        @Override
        public boolean hasArguments() {
            return true;
        }
    
        @Override
        public boolean hasParenthesesIfNoArguments() {
            return true;
        }
    
        @Override
        public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException {
            return firstArgumentType;
        }
    
        @Override
        public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException {
            return "any(" + args.get(0) + ")";
        }
    }
    

    您必须在方言中注册该功能。

    【讨论】:

    • 再次感谢!!!! e2.col3 = FUNCTION('ANY', e1.col3Arr) 这行得通!!!
    • (e2.col3 = FUNCTION('ANY', e1.col3Arr) 拯救了我的一天:) 谢谢!
    【解决方案2】:

    根据hibernate documentation:

    在讨论数组时,了解 SQL 数组类型和作为应用程序域模型的一部分映射的 Java 数组之间的区别很重要。

    并非所有数据库都实现 SQL-99 ARRAY 类型,因此,Hibernate 不支持本机数据库数组类型。

    因此,HQL 中不存在与 PSQL ANY 等效的功能。

    【讨论】:

    • 您能告诉我如何根据包含特定值的数组加入表格吗?
    • 我看到两个选项:1)在这里使用本机 sql。 2)尝试通过注册一个负责比较e2.col3=ANY(e1.col3Arr)的函数来扩展你的hibernate方言,然后在HQL中使用这个函数。而且您还需要编写自己的hibernate custom type 或使用诸如this one 之类的库
    • 我尝试使用本机 sql 但我得到 org.hibernate.MappingException: No Dialect mapping for JDBC type: 2003. 如何在 PostgresqlDialect 中注册数组类型
    • 查看 hibernate 提供的方言的实现。我想你可以在那里找到一些例子。
    猜你喜欢
    • 2019-08-10
    • 2015-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    相关资源
    最近更新 更多