I would like to use the Spring Data Projection technique in order to extract from a table only some fields (and not all fields of the table).
As described in the documentation (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections) I created a simple interface, for example:
interface NamesOnly {
String getFirstname();
String getLastname();
}
But I have some problems to use it.
Problem 1:
First of all, I would like to use the name findAll()
to create a query that finds all rows with only two fields (firstName
and lastName
):
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
List<NamesOnly> findAll();
}
But in this case I have these errors (maybe because findAll()
is a method of the JpaRepository
):
- implements org.springframework.data.jpa.repository.JpaRepository.findAll
- The return type is incompatible with JpaRepository.findAll()
Problem 2:
Ok, so I try to change the name of the method to findAllOnlyNames()
:
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
List<NamesOnly> findAllOnlyNames();
}
But now I have this error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property findAllOnlyNames found for type Persona!
Because Spring tries to create a query from the name.
1) Could it be possible to reuse the method name findAll()
without having problems with JpaRepository?
2) Could it be possible to turn off the query creation from the method name (only for some queries, not for all projects or repositories)?
You are on the right track, your findAll()
is in conflict with the ones specified on the existing Spring Data interfaces and you can rename it (as you tried) but it still has to be a name that is compatible with the query derivation mechanism. Try this instead:
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
List<NamesOnly> findAllOnlyNamesBy();
}
This part of the Spring Data JPA documentation explains how the query creation process works:
The mechanism strips the prefixes
find…By
,read…By
,query…By
,count…By
, andget…By
from the method and starts parsing the rest of it.
So you just need to add the By
keyword in the method name, anything after that keyword is treated as a condition, in this case there is no condition so it fetches everything.
To disable the query derivation from the method name you would need to add an @Query(...)
annotation to the method and specify either a JPA or native query instead.
You can specify an explicit query rather than rely on it being derived from the method name.
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
@Query("select p from Persona p")
List<NamesOnly> findAllOnlyNames();
}
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query
Overriding findAll()
(even in the unlikely event it is possible) is probably a bad idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With