【问题标题】:selecting a list from a object in JPA从 JPA 中的对象中选择列表
【发布时间】:2012-01-18 21:13:18
【问题描述】:

我有一个对象,其中包含一个列表作为其字段,该对象映射到数据库。 我正在尝试创建一个查询,该查询将从对象和前面提到的列表中选择一些字段。

对象映射:

@Entity
@Table(name="buys")
@PrimaryKeyJoinColumn(name="buy_id")
public class Buy extends DomainObject implements Serializable {

        @Column(name = "buy_name")
        private String buyName;

        @OneToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE})
        @JoinColumn(name="buy_id", referencedColumnName = "buy_id")
        private List<InsersionOrder> insertionOrders;

      //other fields omitted

}

我正在使用的查询:

"select new com.dtos.domainObjects.BuyDTO(b.id, b.buyName, b.insertionOrders) from Buy b where b.buyGroupId = :groupId and b.isDeleted = false"

运行此查询时,休眠(我的 JPA 供应商)会生成错误查询:

Hibernate: select buy0_.buy_id as col_0_0_, buy0_.buy_name as col_1_0_, . as col_2_0_ from buys buy0_ inner join domain_objects buy0_1_ on buy0_.buy_id=buy0_1_.id inner join insertion_orders insertiono1_ on buy0_.buy_id=insertiono1_.buy_id inner join domain_objects insertiono1_1_ on insertiono1_.io_id=insertiono1_1_.id where buy0_.buy_group_id=? and buy0_1_.is_deleted=0

InsertionOrder 字段也继承自 DomainObject。

如果我省略该列表并仅从 Buy 对象中选择“简单”字段(即 id、name),则查询工作正常。

我错过了什么?

谢谢。

【问题讨论】:

    标签: java hibernate jpa orm


    【解决方案1】:

    此语法从结果集中的每一行创建一个 BuyDTO 实例。即使它有效,它也不会返回您想要返回的内容。集合字段可能不是 HQL 查询的选择子句的一部分。

    第一个解决方案:不返回 DTO,返回实体本身。

    第二种解决方案:选择实体,自己构建 DTO 实例:

    select b from Buy b 
    left join fetch b.insertionOrders i
    where b.buyGroupId = :groupId and b.isDeleted = false
    
    for (Buy b : list) {
        dtoList.add(new BuyDTO(b.getId(), b.getBuyName(), b.getInsertionOrders());
    }
    

    第三种解决方案:选择你想要的,然后自己组装 DTO:

    select b.id, b.buyName, i 
    from Buy b 
    left join b.insertionOrders i
    where b.buyGroupId = :groupId and b.isDeleted = false
    

    在结果的每一行中,您将找到一个 ID、一个 buyName 和一个 insertOrder。因此,您必须在第一次遇到新 ID 时创建一个 DTO,然后在下次遇到此 ID 时将订单添加到已构建的 DTO。

    【讨论】:

    • 为什么集合不能成为 select 子句的一部分?我看到在您的第三个示例中您选择了集合
    • 因为它没有多大意义,而且 Hibernate 会知道结果集中的哪些行应该组合在一起作为同一个列表的一部分。我没有找到 HQL 的任何参考,但 JPA2 规范在第 160 页说:“请注意,必须指定 SELECT 子句以仅返回单值表达式。因此下面的查询无效:SELECT o .lineItems FROM Order AS o"
    • >Hibernate would know which rows of the resultset should be grouped together as part of the same list. - 我不太确定。如果 Hibernate 足够聪明,可以加入每个实体的 ID,它应该知道如何将整个结果集分组到单独的列表中。毕竟,这也是手动代码在做的事情。
    猜你喜欢
    • 2019-09-17
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多