I have an entity representing a MySQL table:
@Entity
@Table(name = "account")
@Getter
@Setter
@SuppressWarnings("serial")
public class AccountEntity implements AccountBaseEntity, AccountRoleEntity, Serializable {
@Id
@GeneratedValue(generator = "uuid2")
@Column(name = "account_id")
private UUID accountId;
@Column(name = "email")
@NotBlank
private String email;
@Column(name = "role")
@NotBlank
private String role;
@Column(name = "creation_time")
@NotNull
private Timestamp creationTime;
}
It implements this interface:
public interface AccountBaseEntity {
UUID getAccountId();
}
And then I have some projections also implementing it. For instance:
public interface AccountRoleEntity extends AccountBaseEntity {
String getRole();
}
This is my repository, which has a dynamic projection:
public interface AccountsRepository extends JpaRepository<AccountEntity, UUID> {
<T extends AccountBaseEntity> T findByEmail(String email, Class<T> type);
}
And I use it with this code:
AccountRoleEntity accountRoleEntity = accountsRepository.findByEmail(email, AccountRoleEntity.class);
I inspect the query setting the Spring-Boot property spring.jpa.show-sql = true
and this is what I see:
Hibernate: select accountent0_.account_id as account_1_0_, accountent0_.creation_time as creation2_0_, accountent0_.email as email3_0_, accountent0_.role as role10_0_ from account accountent0_ where accountent0_.email=?
I was expecting the query to select only the account_id and role columns, but it seems like it is retrieving the entity and converting it to the projection, instead of retrieving the projection itself. Is this a bug or am I doing something wrong?
I just realized this is because AccountEntity
extends AccountRoleEntity
. Is this the normal behaviour?
I want the entity to extend the projection so that I can have a common interface to be used in some methods that should work both with the entity and the projection.
EDIT:
As stated here (https://github.com/spring-projects/spring-data-jpa/issues/2179), this is the expected behaviour. This is solved creating a super interface implemented by both the entity and the projection.