Java JPA/Hibernate-在按超类查询时如何确定子类类型?
我只是在Hibernate中注意到了这个bevahior,并发现它有点令人惊讶(以一种受欢迎的方式)。我有一个名为Java JPA/Hibernate-在按超类查询时如何确定子类类型?,java,hibernate,jpa,Java,Hibernate,Jpa,我只是在Hibernate中注意到了这个bevahior,并发现它有点令人惊讶(以一种受欢迎的方式)。我有一个名为SyncItem的实体类型,它作为许多其他实体的超类。继承策略设置为InheritanceType.JOINED,因此超类中的所有字段都有一个表,而子类表只包含添加到子类中的所有字段,以及对超类表的引用 例如,我的SyncItem表如下所示: mysql> describe syncItems; +------------+--------------+------+-----
SyncItem
的实体类型,它作为许多其他实体的超类。继承策略设置为InheritanceType.JOINED
,因此超类中的所有字段都有一个表,而子类表只包含添加到子类中的所有字段,以及对超类表的引用
例如,我的SyncItem
表如下所示:
mysql> describe syncItems;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| hidden | bit(1) | NO | | NULL | |
| title | varchar(255) | NO | | NULL | |
| createDate | datetime | NO | | NULL | |
| modifyDate | datetime | YES | | NULL | |
| deleteDate | datetime | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
如果我有一个属性
子类,它可能会得到如下表:
mysql> describe properties;
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| syncId | bigint(20) | NO | PRI | NULL | |
| propertyCode | varchar(255) | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
现在我有十几个不同的子类,让我吃惊的是我有一个查询,如:
@NamedQuery(
name="SyncItem.findByTitle",
query="SELECT s FROM SyncItem s WHERE s.title = :title")
当我写这篇文章时,我希望,因为我正在从SyncItem
中进行选择,所以我只会返回超类表中包含的信息(即,我将获得一个SyncItem
实例,而不是属性
实例)。然而,当我运行它时,我发现查询实际上返回了正确的子类实例。这很好,因为它使许多事情更容易实现
然而,我想知道,JPA/Hibernate是如何将子类带回来的?它无法知道给定的标题将映射到属性
,而不会映射到其他内容,而且据我所知,它没有从同步项目
到属性
的直接映射(相反,它必须从属性
映射回同步项目
)。当这个查询执行时,它是否与每个子类表进行连接?如果是这样的话,那么这难道不会让查询变得非常昂贵吗
所以是的,我只是想知道这里的幕后发生了什么。我相信它连接了所有的子类。它可能比不连接更昂贵,但由于键被索引,并且只有一个表将包含所需的键,所以成本并没有不连接高。使用继承不可避免地会有一些开销
您可以查看SQL日志输出,自己查看。是的,它对每个子表执行联接。这很昂贵,但您可以使用其他两种策略中的任何一种来映射继承 您可以找到一个参考,其中说明: 联合策略通常是继承模型中最慢的。 检索任何子类都需要一个或多个数据库联接,并且 存储子类需要多个INSERT或UPDATE语句 3种可用策略中的每一种都有其各自的优点和缺点(如果您更喜欢节省空间而不是时间,或者两者之间的折衷)。选择还取决于您将更频繁地对这些表执行的操作类型。在我粘贴的参考资料中,你会发现每一个都有一个相当好的简单的解释