@Entity public class Users { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "full_name", nullable = false, length = 50) private String fullName; @Column(name = "current_location", nullable = false) private String currentLocation; @Column(name = "gender", nullable = false, length = 6) private String gender; @Column(name = "birth_date", nullable = false) private Timestamp birthDate; }Uso lo siguiente para filtrar al usuario por género
public class SearchSpecification implements Specification<Users> { private List<SearchCriteria> list; public SearchSpecification() { this.list = new ArrayList<>(); } public void add(SearchCriteria criteria) { list.add(criteria); } @Override public Predicate toPredicate(Root<UserActualDatum> root, CriteriaQuery<?> query, CriteriaBuilder builder) { predicates.add(builder.like(root.<String>get(criteria.getKey()), (String) criteria.getValue())); return builder.and(predicates.toArray(new Predicate[0])); } } Pero quiero filtrar a los usuarios por edad, tengo birthDate columna de fecha de nacimiento que almacena la fecha de nacimiento del usuario. Es posible calcular la edad en la base de datos de postgres usando la función AGE() pero cuando llego a Spring Specification Query no puedo calcular la edad desde la fecha de nacimiento y filtrar por edad calculada.
Agrego la columna de edad, podemos obtener la edad sin ningún cálculo
@Entity public class Users { ... @Formula("date_part('year',AGE(current_date,birth_date))") @Column(name = "age") private Integer age; }CREAR FUNCIÓN EN POSTGRES QUE CALCULE LA EDAD
CREATE OR REPLACE FUNCTION get_age( birthday timestamp ) RETURNS integer AS $CODE$ BEGIN RETURN date_part('year',age(birthday)); END $CODE$ LANGUAGE plpgsql IMMUTABLE;Y MODIFICO LA TABLA AGREGANDO la columna de edad que se calculará a partir de fecha_nacimiento
CREATE TABLE Users ( .... birth_date timestamp not null, age text GENERATED ALWAYS AS (get_age(birth_date)) stored ); Ahora puedo filtrar por age , age como un valor entero derivado de birth_date
Cuando llegamos a la consulta de especificación de arranque Spring ahora este trabajo
public class SearchSpecification implements Specification<Users> { private List<SearchCriteria> list; public SearchSpecification() { this.list = new ArrayList<>(); } public void add(SearchCriteria criteria) { list.add(criteria); } @Override public Predicate toPredicate(Root<UserActualDatum> root, CriteriaQuery<?> query, CriteriaBuilder builder) { predicates.add(builder.lessThanOrEqualTo( root.<Integer>get(criteria.getKey()), (Integer) criteria.getValue())); return builder.and(predicates.toArray(new Predicate[0])); } }Recurso: ¿Cómo calcular un atributo de edad derivado en postgresql?