我有这样的实体结构:
@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以及这个特定基本成员的限制。现在这就是乐趣开始的地方:当且仅当当前记录属于派生类的那种类型时,我必须对派生类的restricttingMember做进一步的限制。 这就是我试过的:
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")
)
));
非常感谢你的想法。 拉尔夫
答案 0 :(得分:0)
我知道您可以使用“class”属性查询Named Queries上的discriminator值,就像在select e from SuperEntity e where e.class ='DERIVED'
中一样。我知道它没有使用标准,但也许它可能有所帮助。