使用条件查询检索多态Hibernate对象

时间:2010-07-07 22:52:44

标签: hibernate jpa polymorphism criteria detachedcriteria

在我的模型中,我有一个抽象的“用户”类,以及多个子类,例如Applicant,HiringManager和Interviewer。它们在一个表中,我有一个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> ...

HiringManager(例如):

@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类实际上没有明确的角色属性)
那么我正在尝试做什么的正确方法是什么?

2 个答案:

答案 0 :(得分:18)

我可能会遗漏一些显而易见的事情,但既然你想找到招聘经理,为什么不把HiringManager子类作为班级传递给Criteria

以防万一,您可以使用特殊的class属性将查询限制为子类型。来自Hibernate参考文档:

  

14.9. The where clause

     

...

     

特殊属性class访问   实例的鉴别器值   在多态的情况下   持久性。 Java类名   嵌入在where子句中   转化为其鉴别者价值。

from Cat cat where cat.class = DomesticCat

您也可以将此特殊类属性与Criteria API一起使用,但稍作修改:您必须使用 discriminator值作为值。

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

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

答案 1 :(得分:1)

请注意,这也适用于Joined Subclass继承映射,但有一点需要注意。限制中使用的类必须是具体类。如果你有一个像Animal&lt; - Mammal&lt; - Cat这样的模特,你就不能Restrictions.eq("class", Mammal.class);并期望找回所有的哺乳动物。相反,我不得不使用Restrictions.or来强制它使用所有已知的具体类(使用Restrictions.in()在执行查询时给出了类强制转换异常。)