【问题标题】:Trouble with inner joins in hibernate (HQL)休眠(HQL)中的内部连接问题
【发布时间】:2012-07-27 13:58:03
【问题描述】:

我正在使用 Struts+Spring+Hibernate,但无法正确执行 HQL。

我有四个对象,objectA、objectB、objectC 和 objectD。对象 A 与对象 B 具有一对多关系,并且它们是相关的,因为 ObjectB 具有 FK ObjectA.Id。这种模式在对象中继续存在,即对象 B 与对象 C 等具有一对多关系。

我现在一直在做的是调用“FROM ObjectXVO WHERE objectXId = ?”获取对象列表。我的应用程序变得越来越复杂,所以我需要做一些更复杂的 HQL。

基本上我需要的是,给定 ObjectBVO.objectBId,我需要返回具有给定 ObjectB 的 ObjectA 的某些列,作为给定 ObjectB 一部分的 ObjectC 的某些列,以及作为一部分的 ObjectD 的所有列作为给定 ObjectB 一部分的 ObjectC 的数量。

这是我在 Microsoft SQL Server 中使用的 SQL 语句。它正在工作,希望能展示我的模型。

SELECT ObjectB.ObjectBID, ObjectB.ObjectBName, ObjectC.ObjectCDescription, 
ObjectD.*, ObjectA.ObjectAID
FROM ObjectB, ObjectC, ObjectD, ObjectA
WHERE ObjectB.ObjectBID = 2 
AND ObjectA.ObjectAID = ObjectB.ObjectAID
AND ObjectB.ObjectBID = ObjectC.ObjectBID
AND ObjectD.ObjectCID = ObjectC.ObjectCID

这是我试图用来返回 List

的 DAOimpl 对象中的代码
List<ObjectDVO> objectDs;
try{
String hql = "SELECT ObjectBVO.objectBId, ObjectBVO.objectBName,
    ObjectCVO.objectCDescription, ObjectCVO.objectCId,"
+" ObjectAVO.objectAId, ObjectAVO.objectAName, ObjectDVO"
    +" FROM ObjectBVO, ObjectAVO, ObjectCVO, ObjectDVO"
    +" WHERE ObjectBVO.objectBId = ?"
+" AND ObjectAVO.objectAId = ObjectBVO.objectAId"
+" AND ObjectBVO.objectBId = ObjectCVO.objectBId"
+" AND ObjectDVO.objectCId = ObjectCVO.objectCId";
objectDs = getHibernateTemplate().find(hql, objectBID);
}

这只是抛出一个错误,说 null。我查看了 HQL 文档和一些教程,但还不清楚如何执行更多多个 VO 对象。任何人都可以帮忙吗?谢谢。

【问题讨论】:

    标签: hibernate struts hql


    【解决方案1】:

    您必须为您的实体分配别名,并返回/使用这些别名。

    此外,根据您的描述,您的实体之间应该有 OneToMany/ManyToOne 关联,但您没有任何此类关联。您所拥有的只是指向其他实体的 ID。

    返回多个类似字段的查询不会返回 ObjectDVO 的实例。它将返回一个List&lt;Object[]&gt;,其中每个Object[] 将包含查询返回的值之一:索引0 处的objectBId,索引1 处的objectBName,等等。

    最后,VO 并不是一个实体。您的实体不应命名为 VO。这基本上就像在 Animals 上附加 Fruit 后缀。

    无论如何,如果您保持实体如图所示(您不应该这样做,而是引入关联),您的查询应该如下所示:

    select b.objectBId, b.objectBName, c.objectCDescription, c.objectCId,
           a.objectAId, a.objectAName, d
    from ObjectBVO b, ObjectAVO a, ObjectCVO c, ObjectDVO d
    where b.objectBId = ?
    and a.objectAId = b.objectAId
    and b.objectBId = c.objectBId
    and d.objectCId = c.objectCId
    

    使用 ManyToOne 关联,您可以简单地做

    select d from D d
    inner join fetch d.c c
    inner join fetch c.b b
    inner join fetch b.a a
    

    你会得到一个List&lt;D&gt;。在每个 D 实例上,您都可以这样做

    String nameOfA = d.getC().getB().getA().getName();
    

    最后一点:属性是类的一部分。所以将objectAId 命名为ObjectA 的ID 是多余的。将其命名为 idobjectA.getId()objectA.getObjectAId() 更具可读性。

    【讨论】:

    • 感谢您的精彩回答!如果我可以让它工作,我会尝试一下并将其标记为已回答。
    猜你喜欢
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    相关资源
    最近更新 更多