我有一个这样的实体结构:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="CLASS_TYPE", discriminatorType= DiscriminatorType.STRING)
@DiscriminatorValue(value="SUPER")
public class SuperEntity implements Serializable {
private String anyBaseMember;
... blah blah
}
@Entity
@DiscriminatorValue(value="DERIVED")
public class DerivedEntity extends SuperEntity {
private String restrictingMember;
... getter / setter / blah blah
}
现在中间目标是选择表的所有记录,而不管类类型如何,即我必须选择所有 SuperEntity 类,但带有 where 子句:
CriteriaQuery<SuperEntity> query = criteriaBuilder.createQuery(SuperEntity.class);
Root root = query.from(SuperEntity.class);
query.where(criteriaBuilder.equal(root.get(SuperEntity_.anyBaseMember), "BLAHBLAHBLAH"));
现在,这可以很好地交付各种实体,SuperEntity 和 DerivedEntity,并受到该特定基本成员的限制。现在这是有趣的开始:当且仅当当前记录属于派生类的那种类型时,我必须对派生类的限制成员做进一步的限制。这是我尝试过的:
Root root = query.from(SuperEntity.class);
query.where(criteriaBuilder.and(
criteriaBuilder.equal(root.get(SuperEntity_.anyBaseMember), "BLAHBLAHBLAH"),
criteriaBuilder.or(
criteriaBuilder.notEqual(root.type(), DerivedClass.class),
criteriaBuilder.equal(((Path) root.as(DerivedClass.class)).get(DerivedClass_.restrictingMember), "SNAFU")
)
));
长话短说:它不起作用:
Exception Description: Invalid query key [restrictingMember] in expression.
它不起作用,因为似乎不可能将根转换为任何其他类。至少它不适用于 .as()
我目前完成工作的方法是仅限制 SuperClass 的所有成员,然后在 for 循环中过滤掉所有其他限制。不是最先进的,但到目前为止我唯一的想法。
编辑:找到解决方案!
Root rootBase = query.from(SuperEntity.class);
Root rootDerived = query.from(DerivedClass.class);
query.where(criteriaBuilder.and(
criteriaBuilder.equal(rootBase, rootDerived),
criteriaBuilder.equal(rootBase.get(SuperEntity_.anyBaseMember), "BLAHBLAHBLAH"),
criteriaBuilder.or(
criteriaBuilder.notEqual(rootBase.type(), DerivedClass.class),
criteriaBuilder.equal(rootDerived.get(DerivedClass_.restrictingMember), "SNAFU")
)
));
非常感谢您的想法。拉尔夫