In my DAO layer, I have a Find function like this
public List<?> findCategoryWithSentenceNumber(int offset, int maxRec) {
Criteria crit = getSession().createCriteria(Category.class, "cate");
crit.createAlias("cate.sentences", "sent");
crit.setProjection(Projections.projectionList().
add(Projections.property("title"), "title").
add(Projections.count("sent.id"), "numberOfSentence").
add(Projections.groupProperty("title"))
);
crit.setFirstResult(offset);
crit.setMaxResults(maxRec);
return crit.list();
}
So, in order to read the data, I have to use a Loop (with Iterator
)
List<?> result = categoryDAO.findCategoryWithSentenceNumber(0, 10);
// List<DQCategoryDTO> dtoList = new ArrayList<>();
for (Iterator<?> it = result.iterator(); it.hasNext(); ) {
Object[] myResult = (Object[]) it.next();
String title = (String) myResult[0];
Long count = (Long) myResult[1];
assertEquals("test", title);
assertEquals(1, count.intValue());
// dQCategoryDTO = new DQCategoryDTO();
// dQCategoryDTO.setTitle(title);
// dQCategoryDTO.setNumberOfSentence(count);
// dtoList.add(dQCategoryDTO);
}
My question is: is there any api, framework to easily convert the List<?> result
in to a list of DTO
object (say, DQCategoryDTO) without using any loop, iterator and calling setter/getter to fill the value?
As I explained in this article, you have so many options for mapping your projection to a DTO result set:
DTO projections using Tuple and JPQL
DTO projections using a Constructor Expression and JPQL
DTO projections using Tuple and native SQL queries
This one is available from Hibernate 5.2.11 so yet one more reason to upgrade.
DTO projections using a ConstructorResult
If we use the same
PostDTO
class type introduced previously, we have to provide the following@SqlResultSetMapping
:Now, the SQL projection named native query is executed as follows:
DTO projections using ResultTransformer and JPQL
This time, your DTO requires to have the setters for the properties you need Hibernate to populate from the underlying JDBC
ResultSet
.The DTO projection looks as follows:
DTO projections using ResultTransformer and a Native SQL query
You can use ResultTransformer which can convert from alias to bean (DTO) properties. For usage you can refer to the Hibernate docs here at section 13.1.5
That's exactly the use case for which Blaze-Persistence Entity Views has been created for!
Your DTO looks like
and if you use Spring Data, you can use it in a repository like
Following is the complete example of how addresses are group together based on street name using Projection.
SomeDTO.java