使用条件查询检索多态 Hibernate 对象
在我的模型中,我有一个抽象的“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我可能遗漏了一些明显的东西,但既然您想找到招聘经理,为什么不将
HiringManager
子类作为类传递给Criteria
呢?为了以防万一,有一个特殊的
class
属性可用于将查询限制为子类型。来自 Hibernate 参考文档:您也可以将这个特殊的类属性与 Criteria API 一起使用,但需要进行一个小的更改:您必须使用鉴别器值作为值。
与 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 theCriteria
?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: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.
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.
请注意,这也适用于连接子类继承映射,但有一点需要注意。限制中使用的类必须是具体类。如果您有像 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).