Hibernate HQL:将SQL语句转换为HQL(使用子选择/连接)

时间:2009-09-18 05:25:01

标签: sql hql

我非常感谢您帮助将以下SQL语句转换为有效的HQL语句。我试了好几个小时但没有成功:

SELECT * FROM master as m left outer join (select * from child as c where c.id = (select max(d.id) from child as d where d.MasterFk = c.MasterFk) )as b ON m.id = b.MasterFk;


public class Master {
 private Long id;
 private Collection childs;
 ...
}

public Class Child {
  private Long id;
  private Master master;
}

在Hibernate Mapping File中,我通过标准SET(-Mapping)将Master映射到Child,从Child到Master的关系是多对一关联。 (这很有效。)

==>目标是查询大师只有最新的儿童记录(=只有一个记录!)正确初始化为孩子的SET中的唯一元素......

无论我怎样尝试,我都悲惨地失败了。

非常感谢!

2 个答案:

答案 0 :(得分:0)

为什么要转换 - 使用本机SQL和Hibernate Transformers

答案 1 :(得分:0)

我不确定你能做到这一点。我看到的问题不是查询,而是初始化。如果你没有返回Set的所有对象,那么我不确定Hibernate是否可以初始化Set。

在Hibernate逻辑中,如果在对象图中提供了一个对象(这里是Set)(不是null,没有代理),那么它应该是完整的。 一个只包含一个元素的集合,因此无法加载其他元素,因为它不是代理,不在Hibernate逻辑之外。在Hibernate逻辑中,Set是null,代理或完全加载(除了大型集合的高级案例,它们由批处理加载...... )。

我理解你的需要。请注意,您需要确保将接收此对象图的代码都知道该集合不是真的!

我建议两种选择:

1。用Java创建对象

另一种方法是查询所需的数据,然后在特定的Java代码中填写对象。

查询可能更简单,例如:

    SELECT m.id, max(c.id) 
    FROM master as m 
    left join m.childs as c 
    group by m.id

java代码会根据List<Object[]>结果实现您想要的内容。

或者,你可以 给Master一个合适的构造函数,并使用new(返回List<Master>):

    SELECT new Master(m.id, max(c.id)) 
    FROM master as m 
    left join m.childs as c 
    group by m.id

2。添加成员

您还可以在Master上拥有一名成员latestChild。可以指定映射以完全按照您的需要加载它。

我建议使用一个公式,它的优点是只读。请注意公式采用SQL,而不是HQL。插入与您的子请求对应的SQL。