Hibernate Criteria可以使用Restrictions.in查询子类吗?

时间:2016-02-08 14:37:31

标签: java hibernate

我有许多类作为继承层次结构映射到单个表中。

我想使用以下Criteria查询,但这会产生ClassCastException,因为Class无法投放到String

Set<Class> childClasses = new HashSet<>();
childClasses.add(Child1.class);
childClasses.add(Child2.class);

session.createCriteria(Parent.class)
       .add(Restrictions.in("class", childClasses)
       .list();

我注意到Hibernate支持使用Restrictions.eq("class", childClass)指定单个类,因此我可以使用Disjunction&#39;来解决此问题。我也知道,如果我的resriction基于每个子类的鉴别器字符串,但是我不想使用这些,那么这将有效。

可以这种方式使用Criteria吗? this question接受的答案表明,当课程属于您Criteria所基于的课程的属性时它会起作用,但在我没有这种情况下它似乎无效如上所示。

1 个答案:

答案 0 :(得分:1)

查看源代码,我会说这是一个Hibernate错误。

例如,SimpleExpression(由Restrictions.eq返回)调用criteriaQuery.getTypedValue来处理Class值转换为相应的鉴别值。

InExpression(由Restrictions.in返回)按原样添加值,而不进行转换。这就是为什么你得到ClassCastException的原因,因为后来尝试将Class转换为String(显然你的鉴别器值的类型是String)。< / p>

您可以避免使用此表单直到它已修复(您已经建议了正确的解决方法),或者,如果您真的想坚持直接使用Class对象,那么您可以实现自定义{ {1}}在您的项目中。例如,像:

InExpression

然后您将使用它代替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>(); for (Object value : values) { resultList.add(criteriaQuery.getTypedValue(criteria, CLASS, value)); } return resultList.toArray(new TypedValue[resultList.size()]); } }

Restrictions.in