7

次のエンティティがあります: イベントと属性。イベントは多くの属性を持つことができます。

私が抱えている問題は、イベントとその属性を単一の SQL クエリで返すクエリが見つからないように見えることです。何百万ものイベントを反復処理する必要があり、明らかなパフォーマンス上の理由から、それらすべてを遅延ロードしたくありません。

クエリで fetch を使用してみましたが、属性ごとにイベントが返されます。つまり、イベントに 2 つの属性がある場合、それぞれ 1 つの属性を持つ 2 つのイベントが返されます。

私が欲しいのは、2 つの属性を持つ 1 つのイベントです。

SELECT e FROM Event e LEFT JOIN FETCH e.attributes

DISTINCT を追加すると機能しますが、大規模なデータ セットでは非常に遅い個別の SQL クエリが作成されます。

public class Event {
  @OneToMany(mappedBy = "event", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  public Set<Attribute> getAttributes(){}
}

public class Attribute {
    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "event_id", nullable = false)
    public Event getEvent() {
        return event;
    }
}

解決

JPA ソリューションが見つかりませんでした。代わりに、EntityManager を Hibernate セッションにラップ解除し、@milkplusvellocet が提案したように基準の結果トランスフォーマーを使用しました。これにより、別個の SQL クエリを作成せずに、別個のルート エンティティが取得されます。

Session session = em.unwrap(Session.class);
Criteria criteria = session.createCriteria(Event.class);
criteria.setFetchMode("attributes", FetchMode.JOIN);

criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);  

注意すべきことの 1 つは、ラップされていないセッションから HQL を使用してみたことです。クエリに DISTINCT を追加し、上記の条件ソリューションと同様に、結果トランスフォーマーを DISTINCT_ROOT_ENTITY に設定しました。このようにしても、別個の SQL クエリが作成されます。

4

1 に答える 1

6

が必要ですResultTransformer

次の HQL を試してください。

SELECT DISTINCT e FROM Event e LEFT JOIN FETCH e.attributes

これはCriteriaSpecification.DISTINCT_ROOT_ENTITY、条件クエリで使用するのと同じです。

于 2012-04-12T21:16:51.560 に答える