2012-03-07 12 views
7

Me gustaría una consulta de criterios para instanciar una clase de DTO utilizando un AliasToBeanResultTransformer. El objetivo es producir una lista paginada liviana con ID para futuras acciones para una página de inicio. Esto requiere una consulta de tipo de informe.AliasToBeanResultTransformer (MyDTO.class) no crea una instancia de MyDTO

  Criteria crit = session.createCriteria(Profile.class); 

     crit.createAlias("personalData", "pd"); 
     crit.createAlias("emails", "e"); 
     crit.createAlias("telephones", "t"); 

     ProjectionList properties = Projections.projectionList(); 
     properties.add(Projections.property("id").as("id")); 
     properties.add(Projections.property("pd.lastName").as("lastName")); 
     properties.add(Projections.property("pd.fullName").as("fullName")); 
     properties.add(Projections.property("e.emailAddress").as("email")); 
     properties.add(Projections.property("t.phoneNumber").as("phone")); 

     crit.setProjection(properties); 

     crit.setResultTransformer(new AliasToBeanResultTransformer(ProfileDTO.class)); 
     profiles = crit.list(); 

Esto no crea una instancia de mi clase de DTO. ProfileDTO tiene un constructor coincidente:

public ProfileDTO(Long id, String lastName, String fullName, String email, 
     String phone) { 
    this(id,fullName); 
    this.lastName = lastName; 
    this.email = email; 
    this.phone = phone; 
} 

Y la consulta funciona cuando se construyo ProfileDTO objetos manualmente con las filas de resultados

 List<Object[]> rows = crit.list(); 

     for (Object[] row: rows) { 
      ProfileDTO dto = new ProfileDTO(); 
      dto.setId((Long)row[0]); 
      dto.setLastName((String)row[1]); 
      dto.setFullName((String)row[2]); 
      dto.setEmail((String)row[3]); 
      dto.setPhone((String)row[4]); 
      profiles.add(dto); 
     } 

Mi solución está trabajando muy bien, pero parece innecesario. ¿Qué estoy haciendo mal?

Respuesta

7

El AliasToBeanResultTransformer usa instaladores para rellenar el DTO. Si desea usar un constructor, para crear su instancia de bean, necesita usar un AliasToBeanConstructorResultTransformer.

Su DTO parece tener un setter para todos los elementos de la tupla, a excepción de lastName. quizá este es el problema.

Dicho esto, su código es simple, fácil de mantener y refactorizable. No sería refactorizable con AliasToBeanResultTransformer. Por lo general, prefiero crear instancias de mis DTO, tal como lo hizo.

+0

Gracias JB. Dejaré de preocuparme y abrazaré el bricolaje. Como dices, funciona bien tal como es. – carbontax

+0

¿puedes poner un ejemplo? –

0

tratar con esto:

public List<ProfileDTO> getProfiles() throws HibernateException 
{  
    try { 

     session = HibernateUtil.getSessionFactory().openSession(); 

     Criteria criteria = session.createCriteria(Profile.class); 

     criteria.createAlias("personalData", "pd"); 
     criteria.createAlias("emails", "e"); 
     criteria.createAlias("telephones", "t"); 

     criteria.setProjection(Projections.projectionList() 
        .add(Projections.property("id").as("id")) 
        .add(Projections.property("pd.lastName").as("lastName")) 
        .add(Projections.property("pd.fullName").as("fullName")) 
        .add(Projections.property("e.emailAddress").as("email")) 
        .add(Projections.property("t.phoneNumber").as("phone")) 
     ); 

     criteria.setResultTransformer(Transformers.aliasToBean(ProfileDTO.class)); 

     return (List<ProfileDTO>)criteria.list(); 

    } catch (HibernateException he){ 
     he.printStackTrace(); 
     throw he; 
    } finally { 
     if(session.isOpen()){ 
      session.close(); 
     } 
    } 
} 
Cuestiones relacionadas