Question

I want to use wild card search on a field which is a Long value (in Entity class) and Integer in database.Here Contact is entity class which has field : Id as Long value in entity class and as a Integer in database.The following is code.

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Tuple> query = builder.createTupleQuery();
Root<Contact> root = query.from(Contact.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if (searchCriteria.getContactId() != null) {
    if(searchCriteria.getContactId().contains("%")){                
       predicates.add(builder.like( 

       (root.get(Contact_.id)),-->Note this line

       builder.literal(searchCriteria.getContactId()+"%")));

        }
    }

Here builder.like will not accept root.get(Contact_.id) as Contact_.id is a long value.We will get compilation error here.Here searchCriteria.getContactId() is string value.

Is there any way to cast the root.get(Contact_.id) as string type?

public static volatile SingularAttribute<Contact, Long> id;

So far I have tried with

((Expression<String>)(root.get(Contact_.id).as(String.class).

But i am getting query syntax exception.It is not able to convert it to perfect syntax. It is giving query like -> ( cast(generatedAlias0.id as varchar(255)) but not as ( cast(generatedAlias0.id as string)) when i look at logs.

Was it helpful?

Solution

When i did search with similar tags ,I found a good solution to above problem which uses the criteriabuilder only.I have tried it and Its working fine. We can find it in below link.

JPA: How to perform a LIKE with a NUMBER column in a static JPA MetaModel?

OTHER TIPS

Some CriteriaBuilder's methods specified by JPA (like, notLike, concat, substring, trim, lower, upper, length, locate) can only work with strings thus rejecting the integer expression:

predicates.add(
    Expression<Long> idExpr = root.get(Contact_.id);
    builder.like(idExpr), // error: Expression<String> is expected
    builder.literal(searchCriteria.getContactId() + "%")
);

To workaround the problem you may try to use Hibernate extensions, for example:

  • HCQ (Hibernate Criteria Query) with a little help of a native SQL
Criteria c = session.createCriteria(Contact.class);
c.add(Restrictions.sqlRestriction(" CAST(id AS varchar(255)) LIKE '1%'"));
List<Contact> entities = c.list();
  • HQL (Hibernate Query Language)
Query q = session.createQuery("FROM Contact c WHERE STR(c.id) LIKE '1%'");
List<Contact> c= q.list();
  • SQL
SQLQuery q2 = session.createSQLQuery("SELECT * FROM Contact " +
                                     "WHERE CAST(id AS varchar(255)) LIKE '1%'");
List<Contact> entities = q.getResultList();

Looks like only HQL has STR() expression or I cannot find equivalent in HCQ. Anyway STR(c.id) used in HQL will be translated to CAST(id AS VARCHAR(255)) clause.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top