2011-05-13 6 views
10

Estoy usando JPQL y quiero recibir algunos parámetros normales y una colección en una Expresión de Constructor para crear directamente los objetos DTO. Pero si la colección está vacía, siempre me sale un error, porque él no encuentra el constructor derecha:JPQL: Recibir una Colección en una Expresión de Constructor

El DTO-Clase mira el siguiente:

public class DTO { 
    private long id; 
    private String name; 
    private Collection<Child> children; 

    public DTO (long id, String name, Collection<Child> children){ 
    this.id = id; 
    this.name = name; 
    this.children= children; 
    } 
} 

El niño de clase:

public class Child { 
    private String name; 
    private int age; 
} 

Y ahora la expresión Constructor se ve lo siguiente:

return (List<DTO>) getEm().createQuery("SELECT DISTINCT NEW de.DTO(p.id, p.name, p.childs) 
              FROM Parent p").getResultList(); 

el problema actual es, t En caso de que la Colección p.childs esté vacía, dice que no encuentra el constructor correcto, necesita (largo, String, Child) en lugar de (long, String, Collection).

¿Tiene algún tipo de solución o simplemente no es posible utilizar una Colección en Expresión del constructor?

Ah y una cosa más: si creo fácilmente dos constructores (..., Colección childs AND ..., Child childs) No obtengo ningún resultado, pero tampoco error ... a mis ojos no me satisface realmente: -/

+0

Creo que olvidó publicar su clase 'Parent'. También la forma plural de 'niño' es' niños'. – Behrang

+0

intenté agregar la condición para consultar - "DONDE p.childs NO ESTÁ VACÍA Y TAMAÑO (p.childs) <> 0" –

Respuesta

8

Esto no es una respuesta.

La especificación de JPA 2.0 no permite, por lo que puedo ver, el uso de colecciones como parámetros en expresiones de constructor. Sección 4.8 define una expresión constructor de la siguiente manera:

constructor_expression ::= 
     NEW constructor_name (constructor_item {, constructor_item}*) 
constructor_item ::= 
     single_valued_path_expression | 
     scalar_expression | 
     aggregate_expression | 
     identification_variable 

Un single_valued_path_expression es lo que suena - una expresión de propiedad que apunta a un escalar de algún tipo (tales como p.id), un scalar_expression es también una expresión que apunta a escalar, un aggregate_expression es la aplicación de una función como sum que reduce una expresión multivaluada a una escalar, y una identification_variable es una referencia al tipo que está consultando. Ninguno de los cuales puede ser valorado por colección. Suponiendo que he leído la especificación correcta.

Por lo tanto, si su proveedor de JPA le permite usar un parámetro de valor de colección en una expresión de constructor, es porque va más allá de las especificaciones. Lo cual es muy bueno, pero no es algo en lo que puedas confiar.

+0

Hola Tom Anderson, muchas gracias por esta información. Solo estoy usando Eclipse Link así que supongo, sin usar Hibernate o algo más, que también actúa en una capa superior, no tendré éxito con esto. @Comments: sí, me olvidé de la clase para padres pero también solo tengo una identificación, un nombre y una colección con o sin hijos. Entonces las condiciones como NO ESTÁ VACÍA no cumplirían mi objetivo, también necesito padres sin hijos. Gracias por tu ayuda, también. – Florian

+0

Lo mismo en JPA 2.1, vea el capítulo 4.14 BNF, página 211. –

3

Intenta,

public DTO (long id, String name, Object children) 
1

que tenía un problema similar y trataron de "objeto" en DTO constructor como sugirió James, pero un objeto secundario se pasa en y parece que es sólo el primer hijo en lugar de la lista esperada/matriz de niños.

Terminé con una consulta "normal" creando todos los DTO en un bucle for.

TypedQuery<Parent> query = em.createQuery("SELECT p FROM Parent p", Parent class); 
     List<Parent> list = query.getResultList(); 
     List<DTO> result = new ArrayList<>(); 
     for (Parent p : list) 
     { 
      DTO dto = new DTO(); 
      //set dto props and fill collection 
      result.add(obj); 
     } 
     return result; 
Cuestiones relacionadas