Reputation: 1621
This is how my entity looks like:
@Entity
public class Registration {
@Id
@GeneratedValue
private Integer id;
@org.springframework.format.annotation.DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
}
This is how my repo could look like:
@Query(value = "SELECT * FROM registration WHERE MONTH(date) = ?1 AND YEAR(date) = ?2")
List<Registration> findAll(Integer month, Integer year);
And this will be service:
public List<Registration> getCurrentRegistration() {
LocalDate today = LocalDate.now();
return registrationRepository.findAll(today.getMonth().getValue(), today.getYear());
}
public List<Registration> getRegistrations(Integer month, Integer year) {
return registrationRepository.findAll(month, year);
}
How can I change my native query to be JPA query? Will the JPA query able to work on postgresql and hsqldb? And why JPA queries are the best for spring apps? (or why they are not)
Upvotes: 2
Views: 3449
Reputation: 120
Make a specification class and write the below specification method in it.
import javax.persistence.criteria.Predicate;
import org.springframework.data.jpa.domain.Specification;
public class RegistrationSpecification {
public static Specification<Registration > registrationSpecForDate(
LocalDate invoiceDate ) {
return (root, cq, cb) -> {
List<Predicate> predicates = new ArrayList<Predicate>();
if (invoiceDate!=(null)) {
predicates.add(cb.greaterThanOrEqualTo(root.get("date"),
invoiceDate));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
}
Then in your repository inject this specification in JPA's findAll() method.
`public List<Registration> getRegistrations(LocalDate date) {
return
registrationRepository.findAll
(RegistrationSpecification.registrationSpecForDate(date));
`
Upvotes: 3
Reputation: 9622
You could do this using QueryDSL JPA (https://github.com/querydsl/querydsl/tree/master/querydsl-jpa) to define a predicate:
Predicate createPredicate(Integer month, Integer year) {
return QRegistration.date.year().eq(year).and(QRegistration.date.month().eq(month));
}
Then make your repo extend QueryDslPredicateExecutor:
public interface RegistrationRepository extends JpaRepository<Registration>, QueryDslPredicateExecutor {
// Your query methods here
}
This contains a List<T> findAll(Predicate predicate)
method which you can pass your predicate in to obtain the items you were after, e.g.:
registrationRepository.findAll(createPredicate(1, 1970));
See here for more info about using QueryDSL with Spring: https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
Upvotes: 2