typedquery query ejemplo java jpa criteria-api

java - query - API de criterios JPA con múltiples parámetros



typedquery (3)

Eche un vistazo a esta API de criterios de JPA del sitio. Hay muchos ejemplos.

Actualización: Proporcionar un ejemplo concreto

Busquemos Cuentas con un saldo inferior a un valor específico:

SELECT a FROM Account a WHERE a.balance < :value

Primero crea un generador de criterios

CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Account> accountQuery = builder.createQuery(Account.class); Root<Account> accountRoot = accountQuery.from(Account.class); ParameterExpression<Double> value = builder.parameter(Double.class); accountQuery.select(accountRoot).where(builder.lt(accountRoot.get("balance"), value));

Para obtener el resultado, establezca el (los) parámetro (s) y ejecute la consulta:

TypedQuery<Account> query = entityManager.createQuery(accountQuery); query.setParameter(value, 1234.5); List<Account> results = query.getResultList();

Por cierto: el entityManager se inyecta en algún lugar en un EJB / Service / DAO.

Necesito hacer un método de búsqueda que use la API de criterios JPA con múltiples parámetros. Ahora el problema es que no se requieren todos los parámetros. Entonces, algunos podrían ser nulos y no deberían incluirse en la consulta. Lo he intentado con el CriteriaBuilder pero no pude ver cómo hacerlo funcionar.

Con la API de criterios de Hibernate esto es bastante fácil. Simplemente crea los criterios y luego agrega Restricciones.

Criteria criteria = session.createCriteria(someClass.class); if(someClass.getName() != null) { criteria.add(Restrictions.like("name", someClass.getName()); }

¿Cómo podría lograr lo mismo con la API de criterios de JPA?


El concepto es construir una matriz de javax.persistence.Predicate que contiene solo los predicados que queremos usar:

Ejemplo de entidad a ser consultada:

@Entity public class A { @Id private Long id; String someAttribute; String someOtherAttribute; ... }

Consulta en sí

//some parameters to your method String param1 = "1"; String paramNull = null; CriteriaBuilder qb = em.getCriteriaBuilder(); CriteriaQuery cq = qb.createQuery(); Root<A> customer = cq.from(A.class); //Constructing list of parameters List<Predicate> predicates = new ArrayList<Predicate>(); //Adding predicates in case of parameter not being null if (param1 != null) { predicates.add( qb.equal(customer.get("someAttribute"), param1)); } if (paramNull != null) { predicates.add( qb.equal(customer.get("someOtherAttribute"), paramNull)); } //query itself cq.select(customer) .where(predicates.toArray(new Predicate[]{})); //execute query and do something with result em.createQuery(cq).getResultList();


La respuesta de Mikko funcionó maravillosamente. El único cambio que tuve que hacer fue: en lugar de: cq.select (cliente) .where (predicates.toArray (nuevo Predicate [] {})); REEMPLAZADO CON: predicado [] predicatesarr = predicates.toArray (nuevo predicado [predicates.size ()]); cq.select (cliente) .where (predicatesarr);

En algún lugar, la conversión de lista a matriz en el original no funcionó.