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

发布于 2024-09-09 05:15:05 字数 929 浏览 11 评论 0原文

在我的模型中,我有一个抽象的“User”类和多个子类,例如 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 类确实没有显式的角色属性)
那么做我想做的事情的正确方法是什么?

In my model I have an abstract "User" class, and multiple subclasses such as Applicant, HiringManager, and Interviewer. They are in a single table, and I have a single DAO to manage them all.

User:

@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 (for example):

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

Now if I wanted to, say, get all the hiring managers that are not associated with a department, how would I do that? I imagine it would look something like:

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

But when I run this, Hibernate complains "could not resolve property: role" (Which actually makes sense because the User class really doesn't have an explicit role property)
So what's the right way to do what I'm trying to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吾家有女初长成 2024-09-16 05:15:05

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

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

14.9。 where 子句

...

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

来自 Cat cat,其中 cat.class = DomesticCat

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

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

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

I may be missing something obvious but since you want to find hiring managers, why don't you just pass the HiringManager subclass as the class to the Criteria?

Just in case, there is a special class property that you can use to restrict a query to a subtype. From the Hibernate reference documentation:

14.9. The where clause

...

The special property class accesses
the discriminator value of an instance
in the case of polymorphic
persistence. A Java class name
embedded in the where clause will be
translated to its discriminator value.

from Cat cat where cat.class = DomesticCat

You can use this special class property with the Criteria API too, but with a minor change: you have to use the discriminator value as value.

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

Unlike with HQL, it looks like Hibernate is not doing the translation with the Criteria API. I don't really like the idea of using the discriminator value in the code and there is maybe another cleaner way but I'm not aware of it. But it works.

⒈起吃苦の倖褔 2024-09-16 05:15:05

请注意,这也适用于连接子类继承映射,但有一点需要注意。限制中使用的类必须是具体类。如果您有像 Animal <- Mammal <- Cat 这样的模型,则无法执行 Restrictions.eq("class", Mammal.class); 并期望返回所有哺乳动物。相反,我必须使用 Restrictions.or 和所有已知的具体类来暴力破解它(使用 Restrictions.in() 在执行查询时给出了类转换异常)。

Note that this also works for Joined Subclass inheritance mappings, with one caveat. The class used in the Restriction must be a concrete class. If you have a model like Animal <- Mammal <- Cat, you cannot do Restrictions.eq("class", Mammal.class); and expect to get back all Mammals. Instead, I had to brute force it using Restrictions.or with all known concrete classes (using Restrictions.in() gave a class cast exception when executing the query).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文