There is no easy way to specify a query result type in JPA, or maybe there is and I couldn't find one :)
The problem is twofold, because if you cannot specify a return type, you cannot cache your native query with ehcache. Now, you could say that maybe this is a sign, and you shouldn't cache your queries anyway, or you could just sweat the small stuff, like I do all the time, and find a solution to this tiny issue.
So, if you've made it this far, you are pretty much stuck with writing some sucky code, to cast back to the hibernate session, and set the info.
And now for some (scala) code:
val sql = "select distinct story as story from ...";
val q: Query = getEntityManager().createNativeQuery(sql);
//hello nasty hack
q.asInstanceOf[HibernateQuery].getHibernateQuery().asInstanceOf[SQLQuery].addScalar("story", StandardBasicTypes.LONG);
//next, caching
q.setHint("org.hibernate.cacheable", true);
q.setHint("org.hibernate.cacheRegion", "query.getTopLinks");
The tick is that you cannot cast directly to SQLQuery, you have to cast to HibernateQuery, then call getHibernateQuery, then cast the result to SQLQuery.
Ugly(ish) but usable, just how I like it.
Also, notice the use of StandardBasicTypes.LONG, replacing the old
ps. I've decided to write this after I've found this question on SO.
Hey, thanks for the article!
ReplyDeleteFound this on SO as well - is it a shorter, API version of the same thing...?
q2.unwrap(SQLQuery.class).addScalar("sc_cur_code", StringType.INSTANCE);
(from http://stackoverflow.com/questions/4873201/hibernate-native-query-char3-column)
Hi Ben,
ReplyDeleteyou are right, q.unwrap() works.
sadly, although your way looks smaller, but it is still a cast ;)