7

私はこれらのクラスを持っています:

@Entity
public class Invoice implements Serializable {
    @Id
    @Basic(optional = false)
    private Integer number;

    private BigDecimal value;

    //Getters and setters
}

@Entity
public class InvoiceItem implements Serializable {
    @EmbeddedId
    protected InvoiceItemPK invoiceItemPk;

    @ManyToOne
    @JoinColumn(name = "invoice_number", insertable = false, updatable = false)
    private Invoice invoice;

    //Getters and setters
}

このクエリを実行すると:

session.createQuery("select i from InvoiceItem i").list();

InvoiceItem からレコードを選択するために 1 つのクエリを実行し、10000 の請求書アイテムがある場合、各 InvoiceItem から請求書を選択するために 10000 の追加クエリを生成します。

すべてのレコードを 1 回の SQL でフェッチできれば、もっと良いと思います。実際、なぜそれがデフォルトの動作ではないのか不思議に思います。

それで、どうすればそれを行うことができますか?

4

4 に答える 4

1

はい、必要な設定があります: @BatchSize(size=25). ここで確認してください:

20.1.5. バッチ フェッチの使用

小引用:

バッチ フェッチを使用すると、Hibernate は、1 つのプロキシがアクセスされた場合に、初期化されていない複数のプロキシをロードできます。バッチ フェッチは、レイジー セレクト フェッチ戦略を最適化したものです。バッチ フェッチを構成するには、クラス レベルとコレクション レベルの 2 つの方法があります。

クラス/エンティティのバッチ フェッチは理解しやすくなっています。次の例を考えてみましょう。実行時に 25 個の Cat インスタンスが Session にロードされ、各 Cat はその所有者である Person への参照を持っています。Person クラスはプロキシ lazy="true" でマップされます。すべての cat を繰り返し処理し、それぞれに対して getOwner() を呼び出すと、Hibernate はデフォルトで 25 の SELECT ステートメントを実行して、プロキシされた所有者を取得します。Person のマッピングでバッチサイズを指定することで、この動作を調整できます。

<class name="Person" batch-size="10">...</class>

このバッチサイズを指定すると、Hibernate は上記のように、初期化されていないプロキシにアクセスする必要があるときにオンデマンドでクエリを実行しますが、違いは、アクセスされている正確なプロキシ エンティティをクエリする代わりに、より多くの Person の所有者を一度にクエリすることです。そのため、他の人の所有者にアクセスする場合、このバッチ フェッチによって既に初期化されている可能性があり、実行されるクエリはわずか (25 よりはるかに少ない) だけです。

したがって、その注釈を両方で使用できます。

  • コレクション/セット
  • クラス/エンティティ

ここでも確認してください:

于 2015-01-06T13:35:19.870 に答える