How to use query operators && or @> when creating a native query in hibernate

Viewed 402

CREATE TABLE IF NOT EXISTS posts(
    postid SERIAL NOT NULL,
    owner SERIAL NOT NULL,
    title VARCHAR(100) UNIQUE NOT NULL,
    message VARCHAR(500) NOT NULL,
    continent VARCHAR(100) NOT NULL,
    country VARCHAR(100) NOT NULL,
    state VARCHAR(100) NOT NULL,
    languages VARCHAR(100)[] NOT NULL,
    properties varchar(100) ARRAY NOT NULL,
    PRIMARY KEY (postid),
    FOREIGN KEY (owner) REFERENCES users(userid) ON DELETE CASCADE
);
final Query query = em.createNativeQuery("SELECT postid FROM posts WHERE :properties <@ properties");
query.setParameter("properties", propAux);

I'm migrating my project to hibernate (I'm using the version 1.0.0.Final of javax.persistence.Query), and I can't seem to run that query. It says that <@ operator doesn't work with types bytea and suggests to cast it. I tried casting it to text[], replacing :properties <@ properties with cast(:properties as text[]) <@ cast(properities as text[]) but didn't work either.

Any suggestions?

PS: propAux is an array of Strings.

1 Answers

Assuming that you have the following setup:

create table TST_POSTS
(
   postid int,
   properties varchar(200)[],
   
   primary key (postid)
);

insert into TST_POSTS
values (1, '{"aaa", "bbb"}'), (2, '{"aaa", "ccc"}'), (4, '{"ddd", "ccc"}');

You can write the following query:

import org.hibernate.jpa.TypedParameterValue;
import com.vladmihalcea.hibernate.type.array.StringArrayType;

// ...

List<Integer> results = entityManager
   .createNativeQuery("select postid from TST_POSTS where :prop <@ cast(properties as text[])")
   .setParameter("prop", new TypedParameterValue(StringArrayType.INSTANCE, new String[] {"ccc"}))
   .getResultList();

and you will get the output:

2
4

This approach requires to have hibernate-types as a dependency.

P.S. I tested it with hibernate-types-52 (version 2.10.1) and hibernate 5.4.29.Final. See also this article.

EDIT

You can use the following query for hibernate 5.1.0.Final:

import org.hibernate.Query;
import com.vladmihalcea.hibernate.type.array.StringArrayType;

// ...

Query query = entityManager
   .createNativeQuery("select postid from TEST_SCHEMA.TST_POSTS where :prop <@ cast(properties as text[])")
   .unwrap(Query.class)
   .setParameter("prop", new String[] {"ccc"}, StringArrayType.INSTANCE);

@SuppressWarnings("unchecked")
List<Integer> result = query.list();

and you should use the following dependency:

<dependency>
   <groupId>com.vladmihalcea</groupId>
   <artifactId>hibernate-types-5</artifactId>
   <version>2.11.1</version>
</dependency>

instead of hibernate-types-52.

Related