Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA/Hibernate-在按超类查询时如何确定子类类型?_Java_Hibernate_Jpa - Fatal编程技术网

Java JPA/Hibernate-在按超类查询时如何确定子类类型?

Java JPA/Hibernate-在按超类查询时如何确定子类类型?,java,hibernate,jpa,Java,Hibernate,Jpa,我只是在Hibernate中注意到了这个bevahior,并发现它有点令人惊讶(以一种受欢迎的方式)。我有一个名为SyncItem的实体类型,它作为许多其他实体的超类。继承策略设置为InheritanceType.JOINED,因此超类中的所有字段都有一个表,而子类表只包含添加到子类中的所有字段,以及对超类表的引用 例如,我的SyncItem表如下所示: mysql> describe syncItems; +------------+--------------+------+-----

我只是在Hibernate中注意到了这个bevahior,并发现它有点令人惊讶(以一种受欢迎的方式)。我有一个名为
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种可用策略中的每一种都有其各自的优点和缺点(如果您更喜欢节省空间而不是时间,或者两者之间的折衷)。选择还取决于您将更频繁地对这些表执行的操作类型。在我粘贴的参考资料中,你会发现每一个都有一个相当好的简单的解释