[情景]
我有两个表 - Region和Substation。 区域可以有许多变电站,但变电站只能属于一个区域。 一个地区也不能有任何变电站。即没有变电站的地区。
在模型类中,我有两个类,Region和Substation。 变电站包含一个Region类型的字段,这就是我在Region和Substation之间建立外键关系的方式。
我在Hibernate查询语言上做了正确的外连接,如下所示:
from Substation sub right outer join fetch sub.region
我正在进行右外连接的原因是因为在查询执行后返回的列表中,我还想显示没有变电站的区域。
[数据库]
这是我的区域表的外观:
mysql> select * from region;
+----+----------------+-------+
| id | name | state |
+----+----------------+-------+
| 1 | Entire Network | |
| 4 | aa | AK |
-------Data abbreviated due to space consumption-------
这是我的变电站表的外观:
mysql> select * from substation;
+---------+-------------+-----------+-----------+----+
| name | lon | lat | region_id | id |
+---------+-------------+-----------+-----------+----+
| aga | 3.000000 | 23.000000 | 1 | 1 |
| sjstest | 46.000000 | 22.100000 | 7 | 2 |
----------Data abbreviated due to space consumption--------
在右外连接之后,这就是我得到的:
mysql> select * from substation right outer join region on region.id=substation.region_id;
+---------+-------------+-----------+-----------+------+----+----------------+-------+
| name | lon | lat | region_id | id | id | name | state |
+---------+-------------+-----------+-----------+------+----+----------------+-------+
| aga | 3.000000 | 23.000000 | 1 | 1 | 1 | Entire Network | |
| addtest | -104.501953 | 47.813155 | 1 | 8 | 1 | Entire Network | |
| NULL | NULL | NULL | NULL | NULL | 4 | aa | AK |
----------Data abbreviated due to space consumption-----------------------------------
如您所见,在最后一行中,第一部分为空,因为该区域“aa”没有任何子站。
[问题]
如果有区域没有变电站,我希望hibernate返回一个Substation对象,其他所有数据都设置为null,只有区域数据集。
但我得到的是,只要找到第3行的数据,hibernate就会返回空对象。
所以我的问题是,当我在查询中指定fetch时,为什么hibernate没有进行急切加载。在进行预先加载之后,它应该初始化一个新的Substation对象并在其中设置区域。
在任何情况下,它都不应该返回null。
[实施例]
只是为了演示,这是我打印结果时得到的结果
com.tollgrade.smartgrid.model.Substation@10cc6578
com.tollgrade.smartgrid.model.Substation@ed192112
null
注意第三个是null,因为它有像我在数据库输出中提到的第3行那样的数据。它不应该为空。它必须包含一个substaion对象,除了region域之外,其他所有字段都为null。
[DEBUG]
这是HQL调试输出:
014-05-15 15:50:31.122 DEBUG [org.hibernate.SQL] - select substation0_.id as id91_0_, region1_.id as id85_1_, substation0_.region_id as region2_91_0_, substation0_.name as name91_0_, substation0_.lon as lon91_0_, substation0_.lat as lat91_0_, region1_.name as name85_1_, region1_.state as state85_1_ from smartgrid.substation substation0_ right outer join smartgrid.region region1_ on substation0_.region_id=region1_.id
2014-05-15 15:50:31.123 TRACE [descriptor.sql.BasicExtractor] - found [1] as column [id91_0_]
2014-05-15 15:50:31.123 TRACE [descriptor.sql.BasicExtractor] - found [1] as column [id85_1_]
2014-05-15 15:50:31.123 TRACE [descriptor.sql.BasicExtractor] - found [8] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [1] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [null] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [4] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [2] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [9] as column [id91_0_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [7] as column [id85_1_]
2014-05-15 15:50:31.124 TRACE [descriptor.sql.BasicExtractor] - found [null] as column [id91_0_]
------------------------------------Abbreviated Output------------------------------------------
答案 0 :(得分:0)
hibernate返回null的原因是因为在hibernate查询中:
from Substation sub right outer join fetch sub.region
我们正在返回一个变电站对象,当hibernate找不到变电站时(区域没有任何变电站的情况),它没有任何可以设置相应区域值的对象。
此外,在"之前没有给出任何东西。使hibernate自动修改查询,因此它基本上变为:
select sub from Substation sub right outer join fetch sub.region
从中我可以清楚地看到,我们特意说hibernate让我返回变电站对象。该区域是否急切加载并不重要。当没有要附加的子站时,hibernate不会获取区域区域对象。
我不确定我对hibernate的期望是什么 - 自动创建一个变电站对象并将其所有值设置为null,区域值除外。 Pfff!看看这家伙。哑。
无论如何,正确的查询应该是这样的:
select sub, reg from Substation sub inner join fetch Region reg sub.region = reg.id
此查询将返回两个对象 - Substation和Region。如果变电子为空,那么第一个对象将为空,但您仍将拥有所需的第二个对象。