Search code examples
javaspringspring-data-jpajpql

How can I use fetch join with @OneToOne relationship?


I have entities Post, PostDetail. Those are in one to one relationship, and PostDetail is optional.

class Post {
    @Id
    private int id;

    @Column
    private String title;

    @Column
    private Strint contents;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private PostDetail postDetail;
}

class PostDetail {
    @Id
    private int id;

    @Column
    private boolean duplicated;

    @OneToOne
    private Post post;
}

public interface PostRepository extends JpaRepository<Post, Integer> {
    @Transactional
    @Query("SELECT a FROM Post a LEFT JOIN FETCH a.postDetail")
    public Page<Post> getAll(Example<Post> example, Pageable pageable);

    @Transactional
    @Query("SELECT a FROM Post a LEFT JOIN FETCH a.postDetail")
    public List<Post> getAll();
}

When application is booting up, exception occurs.

Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list ...

What is the problem? I'm trying this to avoid N+1 problem when querying post list (getAll()).


Sorry, I modified my question.

Both of two PostRepository's methods make errors.

first getAll() throws error "query specified join fetching ..."

second getAll() throws error

org.mariadb.jdbc.internal.common.QueryException: Unknown column 'postdetail1_.post_id' in 'field list'


Solution

  • If you want to avoid 1+N queries issue you can use EntityGraph. Just override 'findAll' methods in your custom Repo and use EntityGraph annotation on them, like this:

    public interface PostRepository extends JpaRepository<Post, Integer> {
    
        @Override
        @EntityGraph(attributePaths = {"postDetail"})
        Page<Post> findAll(Pageable pageable);
    
        @Override
        @EntityGraph(attributePaths = {"postDetail"})
        List<Post> findAll();
    }