Java 冬眠n+;1期

Java 冬眠n+;1期,java,hibernate,hibernate-criteria,Java,Hibernate,Hibernate Criteria,我有以下课程: 订单: @Table(name = "ORDERS") public class Order { @Id @Column(name = "order_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "user_id", nullable = false) private Long userId;

我有以下课程:

订单

@Table(name = "ORDERS")
public class Order {

    @Id
    @Column(name = "order_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_id", nullable = false)
    private Long userId;

    @JsonManagedReference
    @OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
    private Set<OrderDetail> orderDetails;

    @JsonManagedReference(value = "order-note")
    @OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
    private Set<Note> notes;

}
@Table(name = "ORDER_SIZES")
public class OrderSize {

    @Id
    @Column(name = "order_size_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonBackReference
    @ManyToOne
    @JoinColumn(name = "order_detail_id")
    private OrderDetail orderDetail;
}
注释

@Table(name = "ORDER_DETAILS")
public class OrderDetail {
    @Id
    @Column(name = "order_detail_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonBackReference
    @ManyToOne
    @JoinColumn(name = "order_id")
    private Order order;

    @JsonManagedReference
    @OneToMany(mappedBy = "orderDetail", fetch = FetchType.EAGER)
    private Set<OrderSize> orderSizes;

    @JsonManagedReference(value="order-detail-note")
    @OneToMany(mappedBy = "orderDetail", fetch = FetchType.EAGER)
    private Set<Note> notes;
}
@Table(name = "NOTES")
public class Note {

    @Id
    @Column(name = "note_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonBackReference(value="order-note")
    @ManyToOne
    @JoinColumn(name = "order_id", nullable = true)
    private Order order;

    @JsonBackReference(value="order-detail-note")
    @ManyToOne
    @JoinColumn(name = "order_detail_id", nullable = true)
    private OrderDetail orderDetail;
}
我想执行一个查询(使用Hibernate的条件),并获取所有订单及其关联的详细信息、大小和注释

public List<Order> findByUser(Long userId) {
    Criteria criteria = createEntityCriteria();
    criteria.add(Restrictions.eq("userId", userId));
    return (List<Order>) criteria.list();
}
我无法想出一个解决方案,只需一次查询即可获得所需的所有信息。

插入以下内容后:

  • 2附注实体
  • 2个OrderDetail实体(每个包含2个Note实体)
  • 1个订单实体(包含2个OrderDetail实体和2个Note实体)
在订单实体中使用以下注释:

@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private Set<OrderDetail> orderDetails = new HashSet<>();

@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private Set<Note> notes;
但是,如果您仍然面临将数据作为一个查询获取的困难,我建议使用QueryDSL[1],这里有示例和maven设置细节[2]

LE:

如何在QueryDSL中创建查询的示例如下:

public List<Order> findByUserQueryDsl(Long userId) {
    System.out.println("Finding by User ID query dsl");

    EntityManager em = this.entityManagerFactory.createEntityManager();

    return new JPAQuery<>(em, HQLTemplates.DEFAULT)
            .select(QOrder.order)
            .from(QOrder.order)
            .leftJoin(QOrder.order.notes).fetchJoin()
            .leftJoin(QOrder.order.orderDetails, QOrderDetail.orderDetail).fetchJoin()
            .leftJoin(QOrderDetail.orderDetail.notes).fetchJoin()
            .where(QOrder.order.userId.eq(userId))
            .fetch();
}
[1]


[2]

您是否考虑过使用@Fetch@Chris作为第一个参数传递什么?criteria.setFetchMode(“foo”,FetchMode.JOIN)我指的是导致n+1查询的实体关系,也用@Fetch(FetchMode.JOIN)注释它。我会给你一个更完整的答案,但你可以在这段时间内试试。@Chris谢谢你,这似乎并不能解决问题。我得到了相同的n个查询。
Hibernate: 
    select
        this_.order_id as order_id1_3_4_,
        this_.user_id as user_id2_3_4_,
        notes2_.order_id as order_id2_0_6_,
        notes2_.note_id as note_id1_0_6_,
        notes2_.note_id as note_id1_0_0_,
        notes2_.order_id as order_id2_0_0_,
        notes2_.order_detail_id as order_de3_0_0_,
        orderdetai3_.order_detail_id as order_de1_1_1_,
        orderdetai3_.order_id as order_id2_1_1_,
        order4_.order_id as order_id1_3_2_,
        order4_.user_id as user_id2_3_2_,
        ordersizes5_.order_detail_id as order_de2_2_7_,
        ordersizes5_.order_size_id as order_si1_2_7_,
        ordersizes5_.order_size_id as order_si1_2_3_,
        ordersizes5_.order_detail_id as order_de2_2_3_ 
    from
        orders this_ 
    left outer join
        notes notes2_ 
            on this_.order_id=notes2_.order_id 
    left outer join
        order_details orderdetai3_ 
            on notes2_.order_detail_id=orderdetai3_.order_detail_id 
    left outer join
        orders order4_ 
            on orderdetai3_.order_id=order4_.order_id 
    left outer join
        order_sizes ordersizes5_ 
            on orderdetai3_.order_detail_id=ordersizes5_.order_detail_id 
    where
        this_.user_id=?
Hibernate: 
    select
        orderdetai0_.order_id as order_id2_1_0_,
        orderdetai0_.order_detail_id as order_de1_1_0_,
        orderdetai0_.order_detail_id as order_de1_1_1_,
        orderdetai0_.order_id as order_id2_1_1_ 
    from
        order_details orderdetai0_ 
    where
        orderdetai0_.order_id=?
public List<Order> findByUserQueryDsl(Long userId) {
    System.out.println("Finding by User ID query dsl");

    EntityManager em = this.entityManagerFactory.createEntityManager();

    return new JPAQuery<>(em, HQLTemplates.DEFAULT)
            .select(QOrder.order)
            .from(QOrder.order)
            .leftJoin(QOrder.order.notes).fetchJoin()
            .leftJoin(QOrder.order.orderDetails, QOrderDetail.orderDetail).fetchJoin()
            .leftJoin(QOrderDetail.orderDetail.notes).fetchJoin()
            .where(QOrder.order.userId.eq(userId))
            .fetch();
}
select
    order0_.order_id as order_id1_3_0_,
    notes1_.note_id as note_id1_0_1_,
    orderdetai2_.order_detail_id as order_de1_1_2_,
    notes3_.note_id as note_id1_0_3_,
    order0_.user_id as user_id2_3_0_,
    notes1_.order_id as order_id2_0_1_,
    notes1_.order_detail_id as order_de3_0_1_,
    notes1_.order_id as order_id2_0_0__,
    notes1_.note_id as note_id1_0_0__,
    orderdetai2_.order_id as order_id2_1_2_,
    orderdetai2_.order_id as order_id2_1_1__,
    orderdetai2_.order_detail_id as order_de1_1_1__,
    notes3_.order_id as order_id2_0_3_,
    notes3_.order_detail_id as order_de3_0_3_,
    notes3_.order_detail_id as order_de3_0_2__,
    notes3_.note_id as note_id1_0_2__ 
from
    orders order0_ 
left outer join
    notes notes1_ 
        on order0_.order_id=notes1_.order_id 
left outer join
    order_details orderdetai2_ 
        on order0_.order_id=orderdetai2_.order_id 
left outer join
    notes notes3_ 
        on orderdetai2_.order_detail_id=notes3_.order_detail_id 
where
    order0_.user_id=?