
Jakarta EE 12 の Jakarta Persistence 4.0 では @OneToOne @ManyToOne リレーションのデフォルトフェッチタイプの指定が変更された。
Issue と pull request は以下。
- https://github.com/jakartaee/persistence/issues/409
- https://github.com/jakartaee/persistence/pull/455
@OneToOne と @ManyToOne の FetchType のデフォルトは 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.xml で default-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();