1

Using a JPA2 Criteria Query we can project the final result on a DTO (for instance) like this:

query.select(builder.construct( ProductGridDTO.class,
        root.get(Productos_.proId),
        root.get(Productos_.proAlias),
        root.get(Productos_.proNombre),
        companies.get(Companias_.ciaNombre),
        companies.get(Companias_.ciaId)));

However this method is dependant of the order of arguments in my DTO class, which is plain wrong. Using the old (now deprecated) hibernate criteria API we could use the projection list:

ProjectionList projectionList = Projections.projectionList();

    projectionList.add(Projections.property("id"), "id");
    projectionList.add(Projections.property("name"), "name");

Which is not dependent of the parameter order of the DTO.

Is it possible to use a similar strategy in JPA?

tggm
  • 973
  • 2
  • 15
  • 41

2 Answers2

0

I don't think so, the argument order must match in JPA. This could be because, until Java 8, parameter names were only available if the bytecode includes debug information. My guess is that most JPA providers end up calling Constructor.newInstance() and here the argument must be ordered correctly.

Klaus Groenbaek
  • 4,820
  • 2
  • 15
  • 30
0

I moved on to QueryDSL which provides a higher level abstraction and solves this projection issue. So a query to load an entity and return a DTO for said entity becomes:

public List<CompanyDTO> findByCompanyId(String companyId) {
    JPAQuery<?> query = new JPAQuery<Void>(em);

    QCompany company = QCompany.company;

    return query.from(company)
            .where(company.companyId.eq(companyId))
            .select(Projections.constructor(CompanyDTO.class, company))
            .fetch();
}

Where CompanyDTO contains a constructor for the company Entity.

tggm
  • 973
  • 2
  • 15
  • 41