【问题标题】:Retrieving Polymorphic Hibernate Objects Using a Criteria Query使用条件查询检索多态休眠对象
【发布时间】:2011-03-13 02:06: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 类确实没有明确的角色属性)
那么做我想做的事情的正确方法是什么?

【问题讨论】:

    标签: hibernate jpa polymorphism criteria detachedcriteria


    【解决方案1】:

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

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

    14.9. The where clause

    ...

    特殊属性class 访问 实例的鉴别器值 在多态的情况下 坚持。 Java 类名 嵌入 where 子句将是 翻译成它的鉴别器值。

    from Cat cat where cat.class = DomesticCat
    

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

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

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

    【讨论】:

    • 并且可以在查询中使用HiringManager.class的值以及discriminator的值;所以可以写成:c.add(Restrictions.eq("class", HiringManager.class));
    • 在 HQL 中,您可以像 alias.class = HiringManager 一样使用它,而无需 .class 后缀。
    • @Pascal Thivent 在这种情况下我如何按班级订购。 ?????.???(??.???(????.???("?????"))); ?????.???(??.????(????()。????(??.?????????(???????? )));然后我收到错误无法在此 ManagedType 上找到具有给定名称 [class] 的属性
    【解决方案2】:

    请注意,这也适用于 Joined Subclass 继承映射,但有一点需要注意。限制中使用的类必须是具体类。如果你有一个像 Animal Restrictions.eq("class", Mammal.class); 并期望取回所有的哺乳动物。相反,我不得不使用 Restrictions.or 对所有已知的具体类进行暴力破解(使用 Restrictions.in() 在执行查询时会出现类转换异常)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 2011-06-08
      • 2019-07-23
      • 2015-08-14
      • 1970-01-01
      相关资源
      最近更新 更多