You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Even if an interface projection (DTO) is used as the return type of the findAll() method of a repository, the method returns the entity associated with the repository, instead of the DTO.
I create an entity (reduced for compactness):
@Entity@Table(name = "arpsi")
publicclassArpsi {
@Id@GeneratedValue(strategy = GenerationType.AUTO)
privateLongid;
privateStringnombre;
privateStringcodigo;
@JsonRawValueprivateStringdph;
// getters and setters not shown
}
I use a service that uses the repository to retrieve the data. I use ArpsiDTO as the return type in every step, but the service gets the Entity instead of the DTO (with errors due to lazy initialization of a collection).
I tested it with several repositories, and only methods that include any condition (findByX or similar) return the DTO.
Converting the ArpsiDTO to a class, and using a constructor based projection with a custom query for the findAll() method works as expected (returns the DTO):
@Query("SELECT new com.equixlab.api.model.augas.arpsi.ArpsiDTO(a.id, a.nombre, a.codigo) FROM Arpsi a")
Iterable<ArpsiDTO> findAll();
It also works if we create a method with an always true condition, such as:
Iterable<ArpsiDTO> findAllByIdNotNull();
I suppose this happens with all the methods that exist in the CrudRepository interface and expose in a Repository interface (inspecting the CrudRepository interface, the methods use <T> or <S extends T>, so a DTO cannot be used/returned).
Is this by design? I could not find anything in the docs.
The text was updated successfully, but these errors were encountered:
findAll is a method that is defined in CrudRepository and implemented in SimpleJpaRepository. Without @Query, findAll maps to SimpleJpaRepository.findAll() which is a regular Java method that isn't aware of the repository definition (and it can't ever be).
Therefore projections do not work with implementation methods.
Adding @Query turns the method into a query method using query derivation and because the query mechanism is different, the method gets enabled for projections. We should mention this in our documentation.
mp911de
changed the title
Repository findAll() ignores interface projection and returns entity
Document that simple base-repository method overrides cannot return projections
Oct 5, 2021
mp911de
transferred this issue from spring-projects/spring-data-jpa
Oct 5, 2021
findAll is a method that is defined in CrudRepository and implemented in SimpleJpaRepository. Without @Query, findAll maps to SimpleJpaRepository.findAll() which is a regular Java method that isn't aware of the repository definition (and it can't ever be).
Therefore projections do not work with implementation methods.
Adding @Query turns the method into a query method using query derivation and because the query mechanism is different, the method gets enabled for projections. We should mention this in our documentation.
This is what I deducted after reviewing the CrudRepository interface. Adding this explanation to the documentation would help newcomers like me.
Thank you!
Even if an interface projection (DTO) is used as the return type of the findAll() method of a repository, the method returns the entity associated with the repository, instead of the DTO.
I create an entity (reduced for compactness):
I create a DTO with fewer fields:
I create a repository:
I use a service that uses the repository to retrieve the data. I use ArpsiDTO as the return type in every step, but the service gets the Entity instead of the DTO (with errors due to lazy initialization of a collection).
I tested it with several repositories, and only methods that include any condition (findByX or similar) return the DTO.
Converting the ArpsiDTO to a class, and using a constructor based projection with a custom query for the findAll() method works as expected (returns the DTO):
It also works if we create a method with an always true condition, such as:
I suppose this happens with all the methods that exist in the CrudRepository interface and expose in a Repository interface (inspecting the CrudRepository interface, the methods use
<T>
or<S extends T>
, so a DTO cannot be used/returned).Is this by design? I could not find anything in the docs.
The text was updated successfully, but these errors were encountered: