我有一个未规范化的表,如
__________________________________
| id | id_parent | id_child | flag |
| 1 | 1 | 7 | 1 |
| 2 | 1 | 8 | 1 |
| 3 | 2 | 7 | 0 |
__________________________________
我想映射到之类的东西
________ _______
| Parent | -->* | Child |
________ _______
通过一个琐碎的映射,我得到了如我所期望的子代重复(尽管当我期望4时,我为id=1的父代得到了6个子代)。
<class name="com.example.Parent" table="unnormalized_table">
<id name="id" column="ID_PARENT" type="long" access="field" />
<bag name="childs" lazy="false" mutable="false" fetch="join" access="field" where="FLAG = 1">
<key column="ID_PARENT" />
<one-to-many class="com.example.Child"/>
</bag>
</class>
相反,使用加载器:
<class name="com.example.Parent">
<id name="id" column="ID_PARENT" type="long" access="field" />
<bag name="childs" lazy="false" mutable="false" fetch="join" access="field" where="FLAG = 1">
<key column="ID_PARENT" />
<one-to-many class="com.example.Child"/>
</bag>
<loader query-ref="retrieveParent" />
</class>
<sql-query name="retrieveParent">
<return alias="p" class="com.example.Parent" />
select ? as {p.id} from dual
</sql-query>
但是通过这个映射Hibernate执行这个查询:
select ... from Parent this_
left outer join unnormalized_table u_
on this_.ID_PARENT=u_.ID_PARENT
and (
u_.FLAG = 1
)
where
this_.ID_PARENT=?
显然,查询失败是因为找不到表Parent。问题是加载程序没有被执行
在这篇文章中,Hibernate记录了一些东西:
调试org.hibernate.cfg.NamedSQLQuerySecondPass-命名SQL查询:
调试org.hubinate.impl.SessionFactoryImpl-检查命名SQL查询
调试org.hubinate.loader.custom.sql.SQLCustomQuery-启动sql查询的处理
调试org.hubinate.loader.custom.sql.SQLQueryReturnProcessor-映射ping别名[sh]到实体后缀[0_]
但我只得到第一种日志。我缺少一些休眠配置来激活加载程序?
我不知道为什么问题中发布的映射一开始不起作用,但加载程序不需要配置即可工作,只需使用会话#get或会话#load,查询显然不会起作用。
但是,如果我们想实现lazy=false+fetch=join,我们必须显式执行,否则hibernate将首先执行自定义查询,然后解析join。
这个映射完成了工作。
<class name="com.example.Parent">
<id name="id" column="ID_PARENT" type="long" access="field" />
<!-- lazy and fetch attributes doesn't matter because we must do the fetch join explicitly -->
<!-- same for the where clause -->
<!-- I don't know if the mutable attribute is used by hibernate in this case -->
<bag name="childs" lazy="false" mutable="false" fetch="join" access="field" where="FLAG = 1">
<key column="ID_PARENT" />
<one-to-many class="com.example.Child"/>
</bag>
<loader query-ref="retrieveParent" />
</class>
<sql-query name="retrieveParent">
<return alias="p" class="com.example.Parent" />
<return-join alias="childs" property="p.childs"/>
<![CDATA[select :parentId as {p.id},{childs.*} from dual left join (select * from unnormalized_table where flag = 1) childs on :parentId = childs.id_parent]]>
</sql-query>