繁体   English   中英

使用ltree本机命名查询休眠

[英]hibernate with ltree native named query

我正在尝试运行包含ltree函数和运算符的PostgreSQL本机查询。

定义如下:

@NamedNativeQuery(
            name = "pathSegmentQuery",
            query = "select ltree2text(okm_path) as okm_path, " +
                    "       index(okm_path, text2ltree(:lastSegment)) + 2 <> nlevel(okm_path) as haschild, " +
                    "       case " +
                    "         when index(okm_path, text2ltree(:lastSegment)) + 1 <> nlevel(okm_path) " +
                    "                 then ltree2text(subpath(okm_path, index(okm_path, text2ltree(:lastSegment)) + 1, 1)) " +
                    "           end as child " +
                    "from document " +
                    "where okm_path ~ :pathLike " +
                    "and " +
                    "index(okm_path, text2ltree(:path)) + 1 <> nlevel(okm_path) ",
            resultSetMapping = "pathSegmentQueryRSMapping")

调用方式如下:

public List<PathSegment> getPathChildren(String path, String lastSegment) {
    Query query = entityManager.createNamedQuery("pathSegmentQuery");
    String pathLike = "'*." + path + ".*'";

    query.setParameter("path", path);
    query.setParameter("pathLike", pathLike);
    query.setParameter("lastSegment", lastSegment);

    return query.getResultList();
}

结果为错误ERROR: operator does not exist: ltree ~ character varying

当我尝试直接针对数据库运行查询时,它运行正常:

select ltree2text(okm_path) as okm_path,
   index(okm_path, text2ltree('_root_')) + 2 <> nlevel(okm_path) as haschild,
   case
     when index(okm_path, text2ltree('_root_')) + 1 <> nlevel(okm_path)
             then ltree2text(subpath(okm_path, index(okm_path, text2ltree('_root_')) + 1, 1))
       end as child
from document
where
    okm_path ~ '*._root_.*'
and
    index(okm_path, text2ltree('_root_')) + 1 <> nlevel(okm_path)

从错误很明显,休眠(?)不喜欢在th右侧的类型~运算符,但你可以看到,我使用在以后的查询字符串,并能正常工作。

那么,我需要与休眠查询一起做什么才能成功运行查询?

编辑:当我将okm_path ~ :pathLike替换为"where okm_path ~ '*._root_.*' "我将得到:

org.postgresql.util.PSQLException: ERROR: syntax error at position 0错误

冬眠:5.2.9。最终

PostgreSQL的:9.2.23

错误

operator does not exist: ltree ~ character varying

应该读为

operator does not exist: <left_data_type> <operator> <right_data_type> varying

这意味着未为这些数据类型定义运算符。 例如,当运算符的左侧为整数而右侧为varchar时,将发生时间为ERROR: operator does not exist: integer = character varying

这里的问题是当您设置右侧的值时,

query.setParameter("pathLike", pathLike) 

pathLike是一个字符串。 因此Postgres认为这是将ltree与字符串进行比较。 直接执行SQL时,右侧将被视为ltree表达式而不是字符串。

我不确定这是否行得通,但是可以尝试将ltree直接转换为varchar吗,但是可以尝试吗?

query.setParameter("pathLike", pathLike, Hibernate.OBJECT)

另请参见JDBC中到Postgres ltree的Java类型

事实证明,对lquery进行操作时需要调用lquery()函数。

所以我的查询翻译成

...
where okm_path ~ lquery(:pathLike)
...

这解决了问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM