I am trying to run PostgreSQL native query that contains ltree
functions and operators.
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
.
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.
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:
org.postgresql.util.PSQLException: ERROR: syntax error at position 0
error
hibernate: 5.2.9.Final
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
.
The problem here is when you set the value for right side,
query.setParameter("pathLike", pathLike)
pathLike
is a string. So Postgres sees this as comparing a ltree to a string. When you execute the SQL directly the right hand side is taken as a ltree expression than a string.
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?:
query.setParameter("pathLike", pathLike, Hibernate.OBJECT)
See also Java type in JDBC to Postgres ltree
it turned out that there is lquery()
function that needs to be called when you do operations against lquery.
so my query translates to
...
where okm_path ~ lquery(:pathLike)
...
and this solves the problem
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.