简体   繁体   English

使用ltree本机命名查询休眠

[英]hibernate with ltree native named query

I am trying to run PostgreSQL native query that contains ltree functions and operators. 我正在尝试运行包含ltree函数和运算符的PostgreSQL本机查询。

Here's the definition: 定义如下:

@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")

invoked like: 调用方式如下:

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();
}

result is error ERROR: operator does not exist: ltree ~ character varying . 结果为错误ERROR: operator does not exist: ltree ~ character varying

when I try to run the query directly against database it runs ok: 当我尝试直接针对数据库运行查询时,它运行正常:

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)

from the error it's obvious that hibernate(?) dislikes the type on the right side of th ~ operator, but as you can see, I am using the string in the later query and works fine. 从错误很明显,休眠(?)不喜欢在th右侧的类型~运算符,但你可以看到,我使用在以后的查询字符串,并能正常工作。

So what do I need to do with hibernate query to run the query successfully? 那么,我需要与休眠查询一起做什么才能成功运行查询?

EDIT: when I replace okm_path ~ :pathLike for "where okm_path ~ '*._root_.*' " I will be given: 编辑:当我将okm_path ~ :pathLike替换为"where okm_path ~ '*._root_.*' "我将得到:

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

hibernate: 5.2.9.Final 冬眠:5.2.9。最终

postgresql: 9.2.23 PostgreSQL的:9.2.23

The error 错误

operator does not exist: ltree ~ character varying

should be read as 应该读为

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

Which means the operator is not defined for these data types. 这意味着未为这些数据类型定义运算符。 This happens when, for example, the left side of the operator is a integer and the right side a varchar, the error that time would be ERROR: operator does not exist: integer = character varying . 例如,当运算符的左侧为整数而右侧为varchar时,将发生时间为ERROR: operator does not exist: integer = character varying

The problem here is when you set the value for right side, 这里的问题是当您设置右侧的值时,

query.setParameter("pathLike", pathLike) 

pathLike is a string. pathLike是一个字符串。 So Postgres sees this as comparing a ltree to a string. 因此Postgres认为这是将ltree与字符串进行比较。 When you execute the SQL directly the right hand side is taken as a ltree expression than a string. 直接执行SQL时,右侧将被视为ltree表达式而不是字符串。

I am not sure if this will work but can you try ltree can be directly cast to a varchar, but can you try this?: 我不确定这是否行得通,但是可以尝试将ltree直接转换为varchar吗,但是可以尝试吗?

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

See also Java type in JDBC to Postgres ltree 另请参见JDBC中到Postgres ltree的Java类型

it turned out that there is lquery() function that needs to be called when you do operations against lquery. 事实证明,对lquery进行操作时需要调用lquery()函数。

so my query translates to 所以我的查询翻译成

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

and this solves the problem 这解决了问题

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

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