从表中选择所有类型的实体,但限制为派生实体的成员

时间:2013-08-14 11:31:17

标签: java inheritance jpa criteriaquery

我有这样的实体结构:

@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")
        )
));      

非常感谢你的想法。 拉尔夫

1 个答案:

答案 0 :(得分:0)

我知道您可以使用“class”属性查询Named Queries上的discriminator值,就像在select e from SuperEntity e where e.class ='DERIVED'中一样。我知道它没有使用标准,但也许它可能有所帮助。