web-dev-qa-db-ja.com

JPA:空の多辺でフェッチ結果をNULLに結合します

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ユーザーを返さないでください。

11
Dachstein

FETCH JOINは、実際にはSQLで内部結合に解決されます。これは、マップを持たないUserテーブル内のレコード/エンティティが結果セットから削除になることを意味します。マップがない場合でも、すべての結果を取得するには、FETCH JOINLEFTキーワードが必要です。

@Query("SELECT u FROM User u LEFT JOIN FETCH u.maps WHERE u.id = (:id)")
public User findByIdEagerFetch( @Param("id") Long id );
11