java - Can Hibernate Criteria query for subclasses using Restrictions.in? -
i have number of classes mapped inheritance hierarchy single table.
i use following criteria
query results in classcastexception
since class
cannot cast string
.
set<class> childclasses = new hashset<>(); childclasses.add(child1.class); childclasses.add(child2.class); session.createcriteria(parent.class) .add(restrictions.in("class", childclasses) .list();
i note hibernate support specifying single class using restrictions.eq("class", childclass)
can workaround using disjunction
'. know work if resriction based on discriminator strings each subclass prefer not use these.
it possible use criteria
in manner? accepted answer this question suggests works when class property of class basing criteria
on doesn't seem work in case i've shown above.
looking @ source code, hibernate bug.
for example, simpleexpression
(returned restrictions.eq
) calls criteriaquery.gettypedvalue
handles conversion of class
value corresponding discriminator value.
inexpression
(returned restrictions.in
) adds values are, without conversion. that's why classcastexception
, because later attempt cast class
string
made (obviously type of discriminator value string
).
you avoid using form until it's fixed (you suggested proper workarounds), or, if stick using class
objects directly, implement custom inexpression
in project. example, like:
public class classinexpression extends inexpression { private static final string class = "class"; private final collection<class> values; public classinexpression(collection<class> values) { super(class, values.toarray(new object[values.size()])); this.values = values; } @override public typedvalue[] gettypedvalues(criteria criteria, criteriaquery criteriaquery) { if (criteriaquery.gettypeusingprojection(criteria, class).iscomponenttype()) { return super.gettypedvalues(criteria, criteriaquery); } return converttodiscriminatorvalues(criteria, criteriaquery); } private typedvalue[] converttodiscriminatorvalues(criteria criteria, criteriaquery criteriaquery) { list<typedvalue> resultlist = new arraylist<typedvalue>(); (object value : values) { resultlist.add(criteriaquery.gettypedvalue(criteria, class, value)); } return resultlist.toarray(new typedvalue[resultlist.size()]); } }
then use instead of restrictions.in
:
session.createcriteria(parent.class) .add(new classinexpression(childclasses)) .list()
Comments
Post a Comment