从数据库中选择 MappedSuperclass (Hibernate)
Posted
技术标签:
【中文标题】从数据库中选择 MappedSuperclass (Hibernate)【英文标题】:Selecting MappedSuperclass from the database (Hibernate) 【发布时间】:2009-09-15 14:12:39 【问题描述】:问题
我有一个名为 Data 的@MappedSuperclass
作为我数据库中每个实体的父级。它包含 Id 等通用属性。然后我有一个扩展 Data 的实体,由于其子类的通用功能,它也是 @MappedSuperclass
。我的数据库中的映射是正确的。
这是我的层次结构示例
@MappedSuperclass 数据 | @MappedSuperclass +- 员工 | | @实体 | +- 全职员工 | | @实体 | +- 兼职员工 | @实体 +- 商店并且表格已正确映射:
全职员工 兼职的员工 店铺是否可以在数据库中查询所有 Employee 子类(FullTimeEmployee、PartTimeEmployee)作为 Employee 的实例而不在查询中引用子类的名称?
类似
List<Employee> allEmployees = getAllEmployees();
这个想法是,每当我决定创建另一个 Employee 子类(即 AllDayEmployee)时,我都不必更改查询以包含名称。
解决方案
因此,正如Gregory 正确指出的那样,@MappedSuperclass
不可能做到这一点。所以我把它改成了@Entity,因为我想为每个使用InheritanceType.JOINED
的子类保留一个表。
所以上面的层次结构现在是
@MappedSuperclass 数据 | @实体 | @Inheritance(策略=InheritanceType.JOINED) +- 员工 | | @实体 | +- 全职员工 | | @实体 | +- 兼职员工 | @实体 +- 商店桌子还在:
全职员工 兼职的员工 店铺所以现在,我只需调用所有员工:
entityManager.createQuery("from Employee").getResultList();
【问题讨论】:
如果我需要两个不同的@SequenceGenerator
用于 FullTimeEmployee 和 PartTimeEmployee(我正在使用 Oracle 序列)怎么办?作为一个实体,我必须在 Employee 类上指定@Id
。
【参考方案1】:
如果您使用的是@MappedSuperclass,则否
原因是当您将基类定义为@MappedSuperclass 时,没有为基类生成表,而是将所有属性复制到具体表中。在您的示例中,仅存在 FullTimeEmployee、PartTimeEmployee 和 Store 表。
如果您希望能够查询基类实体,则需要为基类选择不同的映射。在基类上使用 @Inheritance 注释并选择 3 种可能的映射策略之一 - SINGLE TABLE、TABLE PER CLASS 或 JOINED
【讨论】:
【参考方案2】:是的
FROM Employee WHERE Employee.<employee only properties> = someValue
但是,正如其他人在这里所说,如果 Employee 实体被映射。您甚至不需要将其映射到它自己的表。请参阅 Hibernate 中的映射策略。
【讨论】:
+1 是的。在 Hibernate 中,你可以选择一个抽象类,你也会得到所有的子类。给出的示例是查询对象,这将返回整个数据库! :-) 鉴于 Employee 是一个具有 @MappedSuperclass 注释的抽象类,我想获取 Employee 的所有子类实例。 “来自员工”查询引发 QuerySyntaxException:员工未映射“ 请查看我的回答,了解为什么它不适用于@MappedSuperclass @Gregory:我假设 Employee 被映射为一个实体。我将更新我的回复以反映这一点。 我还更新了我的问题,以便更清楚地知道哪个是哪个【参考方案3】:我似乎能够使用 hibernate 5.0.8、java 1.8.0_73 和 Oracle 12c 来做到这一点(尽管使用 InheritanceType.JOINED)——要么我误解了,要么 hibernate 已经改变了..
我有以下层次结构:
@MappedSuperclass
@Inheritance(strategy=InheritanceType.JOINED)
CommonRoot
|
| @MappedSuperclass
+- Mapped
| @Entity(name="Concrete1")
| @Table(name="CON1")
+- Concrete1
|
| @Entity(name="Concrete2")
| @Table(name="CON2")
+- Concrete2
我可以执行以下 HQL:
SELECT entityId FROM com.hibernatetest.Mapped ORDER BY entityId ASC
给出这两条 SQL 语句:
select concrete2x0_.entityId as col_0_0_ from CON2 concrete2x0_ order by concrete2x0_.entityId ASC
select concrete1x0_.entityId as col_0_0_ from CON1 concrete1x0_ order by concrete1x0_.entityId ASC
和警告
WARN: HHH000180: FirstResult/maxResults specified on polymorphic query; applying in memory!
但不确定它们的含义,因为这可以使用 SQL 来完成:
(select entityId from CON2
union all
select entityId from CON1)
order by entityId ASC
(如果你愿意,你也可以添加limit/rownum子句,虽然这有点笨拙:
select * from (
(select * from (select entityId from CON2 order by entityId ASC) where rownum <= 10)
UNION ALL
(select * from (select entityId from CON1 order by entityId ASC) where rownum <= 10)
) where rownum <= 10 order by entityId ASC
不知道为什么 hibernate 不能这样做 - 可能会向他们建议。)
【讨论】:
以上是关于从数据库中选择 MappedSuperclass (Hibernate)的主要内容,如果未能解决你的问题,请参考以下文章
doctrine2 映射覆盖从 MappedSuperclass 继承的 inversedBy 字段。
春季是不是有 mongoDB 的 @MappedSuperclass 等效注释?
Hibernate中的Entity类之间的继承关系之一MappedSuperclass