21

I have a one to many relationship between User and GameMap. One user can have many maps.

User class:

// LAZY LOADED
@OneToMany(cascade = CascadeType.ALL, mappedBy = "creater")
private final List<GameMap> maps = new ArrayList<>();

However, sometimes I need to eager load the maps. To avoid the LazyInitializationException after closing Session, I have two variants of retrieving Users.

User Repository:

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 );
}

Problem:
However, the JPQL JOIN FETCH variant to eager load in one go the user and his maps returns a NULL user if there are no maps for this user in the table.

Question:
How can I rewrite the JPQL statement in order to retrieve the user and optionally(!) all his maps but if there are no maps, than thats okay, but dont return a NULL user.

1
  • Use "left join" Commented May 9, 2017 at 20:45

1 Answer 1

34

A FETCH JOIN actually will resolve to an inner join in SQL. This means that any records/entities in the User table which have no maps will be removed from the result set. You need the LEFT keyword on your FETCH JOIN to get all the results, even those without a map.

@Query("SELECT u FROM User u LEFT JOIN FETCH u.maps WHERE u.id = (:id)")
public User findByIdEagerFetch( @Param("id") Long id );
Sign up to request clarification or add additional context in comments.

2 Comments

In my case it did not work as I expected. I have one to many relationship, had exactly same problem. I use identical JPQL, and if there's no related entities on "many" end the list of requested entities (like 'user' in example above) is returned orrectly. But if a requested entity refers several related entities (e.g. user having 2 maps in the example) it's repeated several times, once for each related entity. Both in SQL result rows and in java objects. I put 'distinct' to query and it fixed the problem but I wonder if I do it correctly and no problems will arise later.
@tequilacat distinct is specifically for such cases

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.