Reputation: 51
I have a simple REST service that returns user profile entity that has about 20 fields.
I need to implement a functionality to filter the data where last name is required but all other fields (first name, age, city, state, zip, etc. ) are optional.
Is there a way to do it using JpaRepository
without creating a lot of if
/else
statements for every single combination of patamenters?
Upvotes: 4
Views: 9704
Reputation: 182
JpaRepository interface also implements QueryByExampleExecutor interface which provides findAll method for getting data using Query by Example (QBE) technique. That method would be really applicable for your scenario and is actually ideal when entity has a lot of fields and you want user to be able to filter entities by some of them.
Let's say the entity is Person and you want to create endpoint for fetching persons whose properties are equal to the ones which are specified. That could be accomplished with the following code:
Entity class:
@Entity
public class Person implements Serializable {
private Long id;
private String firstName;
private String lastName;
private Integer age;
private String city;
private String state;
private String zipCode;
}
Controller class:
@Controller
public class PersonController {
private PersonService service;
private PersonController(PersonService service) {
this.service = service;
}
@GetMapping
public List<Person> getMatchingPersons(@RequestBody Person personFilter) {
return service.findMatchingPersons(personFilter);
}
}
Service class:
@Service
public class PersonService {
private PersonRepository repository;
private PersonService(PersonRepository repository) {
this.repository = repository;
}
public List<Person> getMatchingPersons(Person personFilter) {
return repository.findAll(Example.of(personFilter));
}
}
Repository class:
@Repository
public class PersonRepository implements JpaRepository<Person, Long> {
}
Upvotes: 3
Reputation: 131496
It is a use case for JPA criteria (available since JPA2).
In indeed as you want to write a dynamic query, above all, you don't want to hard-coded JPQL
queries for each combination and you don't want concatenating chunks of JPQL
either as this is error-prone and not checked at compile time.
Note that in any case (Criteria
or JPQL
) you should check for each possible option if the client has specified it to be able to take them into consideration in the query build.
Now, as you implement the JPARepository
interface, you have two ways :
using List<T> findAll(@Nullable Specification<T> spec);
provided by the JpaSpecificationExecutor
interface that you can also implement in your custom repository.
Enrich the JPARepository
with your own interface that defines a method findAll()
and that takes as parameter an object containing values for the research.
Then create a concrete class to implement JPARepository
.
You would have so the ability to inject the EntityManager
and to use the Criteria
API.
Upvotes: 3
Reputation: 2814
Check this out http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application
Upvotes: -1