Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly cast string to number with JPA2 Criteria API?

I am trying to write a query with subselect where a string is cast to a long. I'm probably missing something?

Query looks like:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Task> query = cb.createQuery(Task.class);

Root<Task> from = query.from(Task.class);

Subquery<Long> subquery = query.subquery(Long.class);
Root<EntityKeyword> fromKeyword = subquery.from(EntityKeyword.class); 
subquery.select(fromKeyword.get(EntityKeyword_.relatedToId).as(Long.class));
subquery.where(cb.like(fromKeyword.get(EntityKeyword_.keyword), term));

query.where(cb.in(from.get(ModelEntity_.id)).value(subquery));

Where EntityKeyword_.relatedToId a is String that requires cast to Long.

But underlying Hibernate fails with exception:

Last cause: No data type for node: org.hibernate.hql.ast.tree.MethodNode 
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'cast' {originalText=cast}
    \-[EXPR_LIST] SqlNode: 'exprList'
       +-[DOT] DotNode: 'entitykeyw1_.keyword' {propertyName=keyword,dereferenceType=ALL,propertyPath=keyword,path=generatedAlias1.keyword,tableAlias=entitykeyw1_,className=l.i.s.m.s.EntityKeyword,classAlias=generatedAlias1}
       |  +-[ALIAS_REF] IdentNode: 'entitykeyw1_.id' {alias=generatedAlias1, className=l.i.s.m.s.EntityKeyword, tableAlias=entitykeyw1_}
       |  \-[IDENT] IdentNode: 'keyword' {originalText=keyword}
       \-[IDENT] IdentNode: 'int8' {originalText=int8}

No idea what's wrong. Any help is appreciated.

I'm using Hibernate 3.6.8-Final

like image 306
Martynas Jurkus Avatar asked Feb 22 '12 11:02

Martynas Jurkus


1 Answers

Below method worked for me to type cast String to other data types using CriteriaBuilder

CriteriaBuilder queryBuilder = em.getCriteriaBuilder();
Expression roomIdInt = queryBuilder.desc(root.get("room").get("id")).as(Integer.class));
//Expression roomIdInt = queryBuilder.desc(root.get("room").get("id")).as(Long.class));
//Expression roomIdInt = queryBuilder.desc(root.get("room").get("id")).as(Double.class));
//Expression roomIdInt = queryBuilder.desc(root.get("room").get("id")).as(Date.class));
//Expression roomIdInt = queryBuilder.desc(root.get("room").get("id")).as(Boolean.class));

Initially I faced many errors using CriteriaBuilder and tried checking the DB logs to check the query which is getting executed. This helped in correcting the HQL as required. The above approach is working fine in PostgreSQL but the solution varies per Database

like image 169
Dinesh Chv Avatar answered Jan 04 '23 15:01

Dinesh Chv