2017-05-26 11 views
1

私のアプリケーションにパフォーマンスの問題があります。Hibernateがあまりにも多くのクエリを作成する

私は以下の関係を持つ3つのエンティティがあります。

one Order => many OrderLines => Many Cards 

データベースからのエンティティの負荷は時間がかかりすぎるカードが遅延ロードをロードしている間、注文ラインは、積極的なロードがロードされています。アプリケーションを流暢にするには、遅延読み込みが必要です。

私は1つのケースに熱心な負荷を設定する必要があり、それを行うには助けが必要です。

私はjhsipsterスタック使用してい

:私は予期しないトークンオーダー(ライン2)

:私は国連のエラーを持って、私は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); 

を書き込もうとしましたJPA

で春ブートを

@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 
     } 
    } 

問題は、すべてのカードのための2つのクエリを実行し、休止状態の参加との要求がロードされない、第二のforeachであります熱心な構成のようなデータ。私を助けるアイデアはありますか?

感謝

+0

あなたの最初のクエリの使用の際には、 'order'と'のように何か他のもの:order'をそれはかなり明らかにHibernateはあなたがあなたにエラーを与える理由は、SQLキーワード、あるとして持ってる。 –

答えて

2

使用 "をフェッチ参加する" 遅延ロードを避けるために。 "フェッチ"結合を使用すると、単一の選択を使用して、親オブジェクトとともに関連付けまたは値のコレクションを初期化できます。これは、コレクションの場合に特に便利です。アソシエーションとコレクションのマッピングファイルの外部結合と遅延宣言を効果的にオーバーライドします。 の詳細については、フェッチ参加ください: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); 
+0

フェッチを結合すると、最初の問題が解決しました。今私は1つだけのクエリを持っています。 2番目の問題:「予期しないトークンの順序」はpostgreキーワードであるため「注文」でした。 ユニットテストで新しい問題が発生しました: org.hibernate.LazyInitializationException:プロキシを初期化できませんでした - セッションなし 問題について考えましたか? – nassim

+0

列名の前後にバッククォート( '')、引用符、二重引用符を使用します。例: 'order' https://www.mkyong.com/hibernate/how-to-use-database-reserved-keyword-in-hibernate/ – Sudhakar

+0

別のトピックの解決策を見つけました。私はhibernate.jdbcを追加しました。use_streams_for_binary:false が設定ファイルにあり、問題が解決されました。今私は本当に答えを理解するために探しています。 – nassim

関連する問題