An existing example does not suit to my scenario, it checks the presence of a parameter to sort by. In my case I would just like to order by a column (created_on
) in DESC order.
So, here is the definition of the specification I'd like to call in the very end, after chaining "-5 other ones:
public static Specification<Event> orderByCreationDate() {
return new Specification<Event>() {
@Override
public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
query.orderBy(criteriaBuilder.desc(root.get("created_on")));
return null;
}
};
}
The shortened version using lambda looks like that:
public static Specification<Event> orderByCreationDate() {
return (root, query, criteriaBuilder) -> {
query.orderBy(criteriaBuilder.desc(root.get("created_on")));
return null;
};
}
Here is the full chained call of the specifications:
Page<Event> eventsPage = historyLogRepository.findAllPaginated(
allEventsWithEventTypesByVaultId(vaultId)
.and(hasNoEventTypeVisibility()).or(hasEventTypeVisibility(visibilities))
.and(hasNoEventTypes()).or(hasEventTypes(types))
.and(creationDateBefore(before))
.and(creationDateAfter(after))
.and(hasNoDocumentId()).or(hasDocumentId(documentId))
.and(orderByCreationDate()),
pageable);
The idea is to replace this native query:
@Query(value = "SELECT * FROM event e " +
"INNER JOIN event_type et ON et.id = e.event_type_id " +
"WHERE e.vault_id = :vaultId AND " +
"(COALESCE(:visibilities) IS NULL OR et.visibility IN (:visibilities)) AND " +
"(COALESCE(:types) IS NULL OR et.name in (:types)) AND " +
"(:before IS NULL OR e.created_on < :before) AND " +
"(:after IS NULL OR e.created_on > :after) AND " +
"(:documentId IS NULL OR e.document_id = :documentId) " +
"ORDER BY e.created_on DESC LIMIT :limit", nativeQuery = true)
List<Event> findAll(@Param("vaultId") String vaultId,
@Param("before") LocalDateTime before,
@Param("after") LocalDateTime after,
@Param("limit") Integer maxNumberOfResults,
@Param("types") List<String> types,
@Param("visibilities") List<String> visibilities,
@Param("documentId") String documented);
with the new one using Specifications:
Page<Event> findAllPaginated(Specification<Event> specification, Pageable pageable);
...
Any idea?
What should I return from the toPredicate
method in this case?