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

max*_*xdj 14 polymorphism hibernate jpa 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> ...
Run Code Online (Sandbox Code Playgroud)

HiringManager(例如):

@Entity
@DiscriminatorValue("HIRING_MANAGER")
public class HiringManager extends User ...
Run Code Online (Sandbox Code Playgroud)

现在,如果我想让所有与部门无关的招聘经理,我该怎么做?我想它看起来像是这样的:

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

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

Pas*_*ent 20

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

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

14.9.where子句

...

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

from Cat cat where cat.class = DomesticCat
Run Code Online (Sandbox Code Playgroud)

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

c.add(Restrictions.eq("class", "HIRING_MANAGER"));
Run Code Online (Sandbox Code Playgroud)

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

  • 并且您可以在查询中使用HiringManager.class的值以及鉴别器的值; 所以它可以写成:c.add(Restrictions.eq("class",HiringManager.class)); (5认同)