【问题标题】:Hibernate make too much queriesHibernate 查询太多
【发布时间】:2017-10-27 01:27:39
【问题描述】:

我的应用程序存在性能问题。

我有三个具有以下关系的实体:

one Order => many OrderLines => Many Cards

从数据库中加载实体需要太多时间,orderLines 是通过预先加载加载的,而 Cards 是通过延迟加载加载的。延迟加载是让应用流畅的必要条件。

我需要为一个案例配置预加载,我需要帮助。

我正在使用 jhsipster 堆栈:spring-boot with JPA

我尝试写 Hql 查询

@Query(value = "from Order as order "
        + "inner join order.orderLines as orderLines "
        + "inner join orderlines.cards gc "
        + "where order.id= :order")
Order findWithDependencies(@Param("order")Long order);

我有一个错误:意外的令牌订单(第 2 行)

我用原生查询试过了

@Query(value = "select * "+ 
        "from order_table ot "+
        "left join order_line ol ON ot.id = ol.order_id "+
        "left join  giftcard gc ON gc.orderline_id = ol.id "+
        "where ot.id=:order", nativeQuery= true)
Order findWithDependenciesNative(@Param("order")Long order);

但是当我这样做时

orderLine.getCard()

从代码中,Hibernate 仍然执行查询以从数据库中获取数据,这导致了我的性能问题。

实体的必要代码:

public class Order implements Serializable {
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "order_id", nullable = false)
    @Size(min = 1)
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    @JsonProperty("detail")
    @Valid
    private List<OrderLine> orderLines = new ArrayList<>();
}
public class OrderLine extends AbstractAuditingEntity implements Serializable, Comparable {
    @OneToMany
    @JoinColumn(name = "orderline_id")
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<Giftcard> giftcards = new HashSet<>();
}

public class Giftcard extends AbstractAuditingEntity implements Serializable, Comparable {
    @ManyToOne(optional = true)
    @JoinColumn(name= "orderline_id")
    @JsonIgnore
    private OrderLine orderLine;
}

我的代码实际上

{
    Order order = orderRepository.findWithDependenciesNative(linkFile.getOrder());
    //Some code
    List<OrderLine> orderLines = order.getOrderLines();
    orderLines.sort(Comparator.comparing(OrderLine::getId));
    for (OrderLine orderLine : orderLines) {
        Stream<Card> cards = orderLine.getCards().stream().sorted(Comparator.comparing(Card::getCardNumber));
        for (Card card : cards.collect(Collectors.toList())) {
        //Some code
        }
    }

问题出在第二个 foreach 中,对于每个卡休眠执行两个查询,并且带有 join 的请求不会像 Eager 配置那样加载数据。你有什么想法可以帮助我吗?

非常感谢

【问题讨论】:

  • 在您的第一个查询中,使用其他名称作为 order:order,因为这显然是一个 sql 关键字,这就是为什么 hibernate 会出现错误。

标签: postgresql hibernate spring-boot orm jhipster


【解决方案1】:

使用“join fetch”来避免延迟加载。 “获取”连接允许使用单个选择来初始化值的关联或集合以及它们的父对象。这在集合的情况下特别有用。它有效地覆盖了关联和集合的映射文件的外部连接和惰性声明。 更多join fetch信息见:Difference between JOIN and JOIN FETCH in Hibernate

@Query("Select order from Order as order "
        + "inner join fetch order.orderLines as orderLines "
        + "inner join fetch orderlines.cards gc "
        + "where order.id= :order")
Order findWithDependencies(@Param("order")Long order);

【讨论】:

  • Join fetch 解决了第一个问题。现在我只有一个查询。第二个问题:“unexpected token order”是因为“order”是postgre的关键词。现在我的单元测试出现了新问题:org.hibernate.LazyInitializationException: could not initialize proxy - no Session 你知道这个问题吗?
  • 在列名周围使用反引号 (``)、引号或双引号。如:ordermkyong.com/hibernate/…
  • 我找到了另一个主题的解决方案。我在配置文件中添加了 hibernate.jdbc.use_streams_for_binary: false ,它解决了这个问题。现在我希望能真正理解答案。
猜你喜欢
  • 2013-06-10
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2017-10-23
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多