Search code examples
javapostgresqlhibernateltree

hibernate with ltree native named query


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


Solution

  • 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