jpa 2.0 - Is it possible to implement an exists query based on @ElementCollection using Jpa criteria query? -
i'm learning jpa criteria query , have no idea of how implement this:
i have entity called restaurant:
@entity @table(name = "t_f2g_restaurant", uniqueconstraints = @uniqueconstraint(columnnames = { "name" })) public class restaurant { @embeddedid @attributeoverrides( { @attributeoverride(name = "value", column = @column(name = "id")) }) private restaurantidentity id; @column(name = "name") private string name; @elementcollection @collectiontable(name = "t_f2g_restaurant_srv_area", joincolumns = @joincolumn(name = "restaurant_id")) @column(name = "zip_code") private list<string> serviceareas = new arraylist<string>(); } now want count restaurants filtering serviceareas, below native sql implentation:
private boolean delegatetonativequery(address deliveryaddress { string sqlstring = "select count(*) t_f2g_restaurant r " + "where exists (select * t_f2g_restaurant_srv_area sa " + "where sa.zip_code = ? , r.id = sa.restaurant_id) "; query query = entitymanager.createnativequery(sqlstring); query.setparameter(1, deliveryaddress.getzipcode()); return ((number) query.getsingleresult()).longvalue() > 0; } but how implement criteria query?
below attempt:
private boolean delegatetocriteriaquery(address deliveryaddress) { criteriabuilder criteriabuilder = entitymanager.getcriteriabuilder(); criteriaquery<long> query = criteriabuilder.createquery(long.class); root<restaurant> restaurant = query.from(restaurant.class); subquery<long> serviceareasubquery = query.subquery(long.class); /* causes t_f2g_restaurant, t_f2g_restaurant_srv_area join root<restaurant> servicearearoot = serviceareasubquery .from(restaurant.class); listjoin<restaurant, string> serviceareas = servicearearoot .joinlist("serviceareas"); serviceareasubquery.select(criteriabuilder.count(servicearearoot)) .where(criteriabuilder. //servicearea represented string, what's attribute name? equal(serviceareas.get("servicearea"), deliveryaddress.getzipcode())); query.select(criteriabuilder.count(restaurant)). where(criteriabuilder.exists(serviceareasubquery)); return entitymanager.createquery(query).getsingleresult() > 0; }
i made now. hope answer helps someone.
criteriabuilder criteriabuilder = entitymanager.getcriteriabuilder(); criteriaquery<restaurant> query = criteriabuilder .createquery(restaurant.class); root<restaurant> restaurants = query.from(restaurant.class); subquery<restaurant> serviceareasfiltering = query .subquery(restaurant.class); listjoin<object, object> serviceareas = serviceareasfiltering .correlate(restaurants).joinlist("serviceareas"); //correlate joins t_f2g_restaurant , t_f2g_restaurant_srv_area serviceareasfiltering.where(criteriabuilder.or( criteriabuilder.equal(serviceareas, deliveryaddress.getstreet1()), //equal against serviceareas use list<string> serviceareas criteriabuilder.equal(serviceareas, deliveryaddress.getstreet2()))); query.where(criteriabuilder.exists(serviceareasfiltering)); return entitymanager.createquery(query).getresultlist(); frankly speaking, don't think criteria api easy read in case. won't switch criteria api unless need return list of restaurants(i need write result mapper if using native sql query).
Comments
Post a Comment