Jakarta Persistence 4.0 - @OneToOne @ManyToOne 関連のデフォルトフェッチタイプ指定 -

Jakarta EE 12 の Jakarta Persistence 4.0 では @OneToOne @ManyToOne リレーションのデフォルトフェッチタイプの指定が変更された。

Issue と pull request は以下。


@OneToOne@ManyToOneFetchType のデフォルトは FetchType.EAGER であり、 これは、N + 1 選択を誘発する悪いデフォルト値である。

しかし、下位互換性維持のため、デフォルト値を FetchType.LAZY に変更することはできない。


Jakarta Persistence 4.0 では、@OneToOne@ManyToOne の定義が以下のように変更された。

public @interface OneToOne {
    // ...
    FetchType fetch() default FetchType.DEFAULT;
}
public @interface ManyToOne {
    // ...
    FetchType fetch() default FetchType.DEFAULT;
}

FetchType.DEFAULT は、デフォルトで FetchType.EAGER として定義される。

FetchType.DEFAULT は、persistence.xmldefault-to-one-fetch-type 要素を指定することで、LAZY に設定できる。

<persistence version="4.0"
             xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
             https://jakarta.ee/xml/ns/persistence/persistence_4_0.xsd">
  <persistence-unit name="default">
    <jta-data-source>java:app/MyApp/MyDS</jta-data-source>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <default-to-one-fetch-type>LAZY</default-to-one-fetch-type>
  </persistence-unit>
</persistence>

これにより、関連のFetchType のデフォルト値を FetchType.LAZY として統一できる。

PersistenceConfiguration を使った場合は以下のように指定できる。

EntityManagerFactory emf = new PersistenceConfiguration()
        .name("OrderManagement")
        . ...
        .defaultToOneFetchType(FetchType.LAZY)
        .createEntityManagerFactory();