JPA CriteriaBuilder – Cómo usar «EN» operador de comparación

¿Puedes ayudarme por favor cómo convertir los siguientes códigos para el uso de «en» operador de criterios constructor?
Necesito filtrar por el uso de la lista/array de nombres de usuario el uso de «en».

También traté de buscar usando JPA CriteriaBuilder – «en» método, pero no puede encontrar un buen resultado.
Así que realmente agradecería también si me puede dar referencia de las URLs de este tema. Gracias.

Aquí es mis códigos:

//usersList is a list of User that I need to put inside IN operator 

CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder();
CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class);

Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class);
criteria = criteria.select(scheduleRequest);

List<Predicate> params = new ArrayList<Predicate>();

List<ParameterExpression<String>> usersIdsParamList = new ArrayList<ParameterExpression<String>>();

for (int i = 0; i < usersList.size(); i++) {
ParameterExpression<String> usersIdsParam = builder.parameter(String.class);
params.add(builder.equal(scheduleRequest.get("createdBy"), usersIdsParam) );
usersIdsParamList.add(usersIdsParam);
}

criteria = criteria.where(params.toArray(new Predicate[0]));

TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria);

for (int i = 0; i < usersList.size(); i++) {
query.setParameter(usersIdsParamList.get(i), usersList.get(i).getUsername());
}

List<ScheduleRequest> scheduleRequestList = query.getResultList();

El interior de la Cadena de Consulta se convierte para abajo, así que no tengo los registros creados por los dos usuarios, ya que es el uso de «Y».

select generatedAlias0 from ScheduleRequest as generatedAlias0 where ( generatedAlias0.createdBy=:param0 ) and ( generatedAlias0.createdBy=:param1 ) order by generatedAlias0.trackingId asc 
InformationsquelleAutor Jemru | 2012-02-17

2 Kommentare

  1. 86

    Si entiendo bien, quieres Unirte a ScheduleRequest con User y aplicar la in cláusula a la userName de propiedad de la entidad User.

    Yo tendría que trabajar un poco en este esquema. Pero puedes probar con este truco, que es mucho más legible que el código que has publicado, y evita la Join parte (porque controla la Join lógica fuera de los Criterios de la Consulta).

    List<String> myList = new ArrayList<String> ();
    for (User u : usersList) {
        myList.add(u.getUsername());
    }
    Expression<String> exp = scheduleRequest.get("createdBy");
    Predicate predicate = exp.in(myList);
    criteria.where(predicate);

    Para escribir más código seguro de que usted también podría usar Metamodelo mediante la sustitución de esta línea:

    Expression<String> exp = scheduleRequest.get("createdBy");

    con esto:

    Expression<String> exp = scheduleRequest.get(ScheduleRequest_.createdBy);

    Si funciona, entonces usted puede tratar de añadir el Join lógica en la Criteria Query. Pero ahora mismo no puedo probarlo, así que prefiero ver si alguien quiere probar.

    • Hola perissf, gracias por su respuesta. Puedo pedir por favor, ¿qué es «ScheduleRequest_»? ¿Cómo puedo crear?
    • Es un Metamodelo de la clase de auto-generado por su JPA proveedor. Si usted está usando Hibernate, echa un vistazo a este enlace docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/…
    • La lectura de mi pseudo-código veo un posible tipo de discrepancia. Son unirse con los nombres de usuario (String) o identificaciones del usuario (Entero Largo)? Pls me dejó saber lo que puedo actualizar mi respuesta
    • Hola perissf, estoy usando la Cadena de nombres de usuario. Sólo estoy siguiendo nuestra arquitectura que no tiene el «_» subrayado bean, así que no estoy seguro de cómo hacerlo. Pero va a tratar de seguir su enlace. gracias.
    • gracias perissf, que trabajó para mí. aunque no he hecho el tipo de seguro. No sé cómo generar de forma automática la clase ScheduleRequest_. muchas gracias! 🙂
    • Es bueno saberlo! Para la auto-generado clases, que son llamados Metamodelo, has leído el enlace que he dado a usted? Si usted tiene problemas en que, de hacer una nueva pregunta con los detalles
    • Estoy consiguiendo no puede emitir a la cadena de error una y otra vez con este

  2. 14

    No es una respuesta perfecta a pesar de que pueden ser fragmentos de código podría ser de ayuda.

    public <T> List<T> findListWhereInCondition(Class<T> clazz,
                String conditionColumnName, Serializable... conditionColumnValues) {
            QueryBuilder<T> queryBuilder = new QueryBuilder<T>(clazz);
            addWhereInClause(queryBuilder, conditionColumnName,
                    conditionColumnValues);
            queryBuilder.select();
            return queryBuilder.getResultList();
    
        }
    
    
    private <T> void addWhereInClause(QueryBuilder<T> queryBuilder,
                String conditionColumnName, Serializable... conditionColumnValues) {
    
            Path<Object> path = queryBuilder.root.get(conditionColumnName);
            In<Object> in = queryBuilder.criteriaBuilder.in(path);
            for (Serializable conditionColumnValue : conditionColumnValues) {
                in.value(conditionColumnValue);
            }
            queryBuilder.criteriaQuery.where(in);
    
        }
    • Muchas gracias @gbagga, esta cosa me ha ayudado mucho! el método anterior (exp.en(milista)) no funciona cuando se está utilizando «CriteriaBuilder». Su método es el que debe ser utilizado para «EN» cláusula cuando se utiliza criteriaBuilder. Felicitaciones!

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea