【问题标题】:How to active an Hibernate loader for custom loading?如何激活 Hibernate 加载器以进行自定义加载?
【发布时间】:2015-12-16 15:45:05
【问题描述】:

我有一个像

这样的非标准化表格
 __________________________________
| id | id_parent | id_child | flag |
| 1  |     1     |    7     |   1  |
| 2  |     1     |    8     |   1  |
| 3  |     2     |    7     |   0  |
 __________________________________

我想映射到类似的想法

    ________        _______
   | Parent | -->* | Child |
    ________        _______

通过一个简单的映射,我得到了我预期的重复的孩子(虽然我得到了 6 个孩子的 id = 1 的父母,而我预期的是 4)。

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

取而代之的是loader:

<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。 问题是加载器没有被执行。

this 帖子中说 Hibernate 记录了一些内容:

调试 org.hibernate.cfg.NamedSQLQuerySecondPass - 命名 SQL 查询:

调试 org.hibernate.impl.SessionFactoryImpl - 检查命名 SQL 查询

调试 org.hibernate.loader.custom.sql.SQLCustomQuery - 开始 sql查询的处理

调试 org.hibernate.loader.custom.sql.SQLQueryReturnProcessor - 映射 ping 别名 [sh] 到实体后缀 [0_]

但我只得到第一种日志。 我缺少一些休眠配置来激活加载器?

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    我不知道为什么问题中发布的映射一开始不起作用,但是让加载器工作不需要配置,只需使用 Session#get 或 Session#load,查询将不起作用很明显。

    但是如果我们想要实现lazy=false + fetch=join,我们必须显式执行,否则hibernate会先执行自定义查询,然后再解析连接。

    这个映射完成了工作。

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

    【讨论】:

      猜你喜欢
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多