UserとGameMapの間には1対多の関係があります。 1人のユーザーが多くのマップを持つことができます。
ユーザークラス:
// LAZY LOADED
@OneToMany(cascade = CascadeType.ALL, mappedBy = "creater")
private final List<GameMap> maps = new ArrayList<>();
ただし、マップを熱心にロードする必要がある場合があります。セッションを閉じた後のLazyInitializationExceptionを回避するために、ユーザーを取得する2つのバリエーションがあります。
ユーザーリポジトリ:
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findById( Long id );
@Query("SELECT u FROM User u JOIN FETCH u.maps WHERE u.id = (:id)")
public User findByIdEagerFetch( @Param("id") Long id );
}
問題:
ただし、JPQL JOIN FETCHバリアントを一度にロードすると、ユーザーはNULLを返し、マップはNULLユーザーを返しますこのユーザーのマップがテーブルにない場合。
質問:
ユーザーとオプションで(!)すべてのマップを取得するためにJPQLステートメントを書き直すにはどうすればよいですか。ただし、マップがない場合は問題ありませんが、NULLユーザーを返さないでください。
FETCH JOIN
は、実際にはSQLで内部結合に解決されます。これは、マップを持たないUser
テーブル内のレコード/エンティティが結果セットから削除になることを意味します。マップがない場合でも、すべての結果を取得するには、FETCH JOIN
にLEFT
キーワードが必要です。
@Query("SELECT u FROM User u LEFT JOIN FETCH u.maps WHERE u.id = (:id)")
public User findByIdEagerFetch( @Param("id") Long id );