使用Criteria API的Hibernate向数据库发送了太多查询

时间:2018-02-22 14:01:22

标签: hibernate jpa jpa-criteria

我的印象是,通过提取hibernate可以减少查询次数,但显然情况并非如此。

这是我的根类:

import scipy.sparse as sparse
idx = [ (1,4,), (2,3,), (0,), (0,3,4,) ]
#create list with pair of row and column
idx_list = [(i, j) for i, tup in enumerate(idx) for j in tup]
#fill sparse matrix with 1 or any other data set and convert to array
arr = sparse.coo_matrix((np.ones(len(idx_list)), zip(*idx_list)), shape = (8, 5)).toarray()

#output
[[0. 1. 0. 0. 1.]
 [0. 0. 1. 1. 0.]
 [1. 0. 0. 0. 0.]
 [1. 0. 0. 1. 1.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]

请注意我的所有关系都是双向的

这是我的标准API查询:

public class Ereturn {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String globalId;
    private String rma;
    @ManyToOne
    @JoinColumn(name = "shipper")
    private User shipper = new User("", UserType.SHIPPER);
    @ManyToOne
    @JoinColumn(name = "consignee")
    private User consignee;
    @ManyToOne
    @JoinColumn(name = "carrier")
    private User carrier = new User("", UserType.CARRIER);
    @JsonManagedReference(value="ereturn-parcel")
    @OneToMany(mappedBy = "ereturn", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Parcel> parcels = new ArrayList<>();
    @JsonManagedReference(value="ereturn-productItems")
    @OneToMany(mappedBy = "ereturn", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    private List<ProductItem> productItems = new ArrayList<>();

...

}

这是发送到数据库的查询:

        CriteriaBuilder builder = em.getCriteriaBuilder();

        CriteriaQuery<Ereturn> criteria = builder.createQuery( Ereturn.class );

        Root<Ereturn> er = criteria.from(Ereturn.class);
        er.fetch("shipper");
        er.fetch("carrier");
        er.fetch("consignee");
        er.fetch("productItems");

        criteria.select( er );

        boolean disabled = false;

        List<Predicate> predicates = new ArrayList<>();

        predicates.add(builder.equal(er.get( "disabled" ), disabled));
        predicates.add(builder.isNotNull( er.get( "scanDateTime" )));
        predicates.add(builder.equal( er.get( "status" ), ReturnStatus.RECEIVED));

        criteria.where(
                builder.and(predicates.toArray(new Predicate[predicates.size()]))
        );

        ers = em.createQuery(criteria).getResultList();

问题:如何更改标准API以减少发送到数据库的查询数量?

注意:理想情况下,我只想发送一个查询

1 个答案:

答案 0 :(得分:0)

实体中有太多EAGER个。尝试标记为LAZY

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "shipper")
private User shipper = new User("", UserType.SHIPPER);

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "consignee")
private User consignee;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "carrier")
private User carrier = new User("", UserType.CARRIER);