如何激活Hibernate加载程序进行自定义加载



我有一个未规范化的表,如

 __________________________________
| 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>

最新更新