15

在我的模型中,我有一个抽象的“用户”类,以及多个子类,例如申请人、HiringManager 和面试官。它们在一个表中,我有一个 DAO 来管理它们。

用户:

@Entity
@Table(name="User")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="role",
    discriminatorType=DiscriminatorType.STRING
)
public abstract class User extends BaseObject implements Identifiable<Long> ...

招聘经理(例如):

@Entity
@DiscriminatorValue("HIRING_MANAGER")
public class HiringManager extends User ...

现在,如果我想获得所有与部门无关的招聘经理,我会怎么做?我想它看起来像:

DetachedCriteria c = DetachedCriteria.forClass(User.class);
c.add(Restrictions.eq("role", "HIRING_MANAGER"));
c.add(Restrictions.isNull("department"));
List<User> results = getHibernateTemplate().findByCriteria(c);

但是当我运行它时,Hibernate 抱怨“无法解析属性:角色”(这实际上是有道理的,因为 User 类确实没有明确的角色属性)
那么做我想做的事情的正确方法是什么?

4

2 回答 2

22

我可能遗漏了一些明显的东西,但既然你想找到招聘经理,为什么不HiringManager把子类作为类传递给Criteria?

以防万一,有一个特殊class属性可用于将查询限制为子类型。从休眠参考文档:

14.9。where 子句

...

在多态持久性的情况下,特殊属性class访问实例的鉴别器值。嵌入在 where 子句中的 Java 类名将被转换为它的鉴别器值。

from Cat cat where cat.class = DomesticCat

您也可以将这个特殊的类属性与 Criteria API 一起使用,但需要做一些小改动:您必须使用鉴别器值作为值。

c.add(Restrictions.eq("class", "HIRING_MANAGER"));

与 HQL 不同,Hibernate 似乎没有使用 Criteria API 进行翻译。我真的不喜欢在代码中使用鉴别器值的想法,也许还有另一种更清洁的方法,但我不知道。但它有效。

于 2010-07-07T23:54:13.723 回答
3

请注意,这也适用于 Joined Subclass 继承映射,但需要注意一点。限制中使用的类必须是具体类。如果你有一个像 Animal <- Mammal <- Cat 这样的模型,你不能做Restrictions.eq("class", Mammal.class);也期望得到所有的 Mammals。相反,我不得不使用 Restrictions.or 对所有已知的具体类进行暴力破解(使用 Restrictions.in() 在执行查询时给出了类强制转换异常)。

于 2012-07-10T15:36:41.363 回答