Spring Boot Data JPA - query using an interface projection returns all fields if there are collections in the projection

Viewed 45

There are several entities in the project, such as User and enum Role, which is used in the User entity as @ElementCollection.

User entity

public class User {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    private String username;

    @Column(unique = true, nullable = false)
    private String email;

    @Column(nullable = false, length = 80)
    private String password;

    @Column(nullable = false)
    private Boolean isActive = false;

    @ElementCollection(fetch = LAZY)
    private Set<Role> roles = new HashSet<>(Set.of(USER));
}

Role enum

public enum Role implements GrantedAuthority {
    USER, ADMIN;
    
    @Override
    public String getAuthority() {
        return name();
    }
}

For the User entity, I created a special projection that includes the following fields, including the role collection:

public interface UserProjection {
    String getUsername();
    String getPassword();
    Set<Role> getRoles();
}

And a JPA repository with a method that finds by username the user using this projection:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    @EntityGraph(attributePaths = {"roles"})
    Optional<UserProjection> findUserByUsername(String username);
}

When I call this method, I run into the problem that the query contains all fields, including those not specified in the projection:

select
        user0_.id as id1_1_,
        user0_.email as email2_1_,
        user0_.is_active as is_activ3_1_,
        user0_.password as password4_1_,
        user0_.username as username5_1_,
        roles1_.users_id as users_id1_2_0__,
        roles1_.roles as roles2_2_0__ 
    from
        users user0_ 
    left outer join
        users_roles roles1_ 
            on user0_.id=roles1_.users_id 
    where
        user0_.username=?

But if I remove the collection from the projection, the query starts working correctly:

select
        user0_.username as col_0_0_,
        user0_.password as col_1_0_ 
    from
        users user0_ 
    where
        user0_.username=?

Can you tell me how to fix this error? I couldn't find any clues, including in the Spring Data JPA documentation, which gave examples of the most basic use cases of projections. Thanks

0 Answers
Related