Reputation: 1313
I'm performing a Query to my DB in JPA. The Query "queries" 4 tables, and the result aggregates columns from that different tables.
My Query is something like:
Query query = em.createQuery("SELECT o.A, o.B, o.C, e.D, c.E FROM Table1 o,
Table2 i, Table3 e, Table4 c WHERE o.X = i.X AND i.Y = e.Y AND i.Z = c.Z");
How can I get the query result and extract the different fields?
I created a class (MyObject) that represents each item of the result list, and I want to convert the query.getResultList()
into a List< MyObject>
.
How can I do it?
Upvotes: 9
Views: 36288
Reputation: 1199
I faced the same issue after a lot of research found this working solution. For my HQL Query, I wanted to get the output of the POJO List, but I was getting a List of Object. This is how you can get the list of your POJO class.
Can achieve this in two ways:
Query query = em.createNativeQuery(sqlQuery, Picking.class);
OR
Query query = em.createQuery(sqlQuery);
Working Example of NativeQuery:
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
@PersistenceContext
protected EntityManager em;
private <T> List getPickingQuery(Map<String, String> searchFields, Map<String, String> orderByFields,
Pageable pageable, String status) {
List resultList = new ArrayList();
try {
String sql = "select * from picking where status = '" + status + "'";
String sqlQuery = createQuery(sql, searchFields, orderByFields);
Query query = em.createNativeQuery(sqlQuery, Picking.class);
setQueryParam(sqlQuery, searchFields);
query.setMaxResults(pageable.getPageSize());
query.setFirstResult((int) pageable.getOffset());
log.info("Query " + query);
resultList = query.getResultList();
} catch (Exception e) {
log.error("Error " + e.getMessage());
}
return resultList;
}
private String createQuery(String sql, Map<String, String> searchFields, Map<String, String> orderByFields) {
for (String paramName : searchFields.keySet()) {
sql = sql.concat(" and " + paramName + " = ?");
}
if (orderByFields != null) {
if (orderByFields.containsKey("key") && orderByFields.containsKey("order"))
sql = sql.concat(" order by " + orderByFields.get("key") + " " + orderByFields.get("order"));
else if (orderByFields.containsKey("key"))
sql = sql.concat(" order by " + orderByFields.get("key"));
}
return sql;
}
private void setQueryParam(String sqlQuery, Map<String, String> searchFields) {
int param = 1;
for (String paramName : searchFields.keySet()) {
query.setParameter(param++, searchFields.get(paramName));
}
}
You can also refer to this link for other cases: https://www.tabnine.com/code/java/methods/javax.persistence.Query/getResultList
Upvotes: 1
Reputation: 5306
You're looking for the SELECT NEW
construct, explained in this answer:
"SELECT NEW your.package.MyObject(o.A, o.B, o.C, e.D, c.E)
FROM Table1 o, Table2 i, Table4 c
WHERE o.X = i.X AND i.Y = e.Y AND i.Z = c.Z"
Of course, your MyObject
must have a matching constructor.
Upvotes: 4
Reputation: 691765
This kind of query returns a List<Object[]>
. So you just need a loop to convert each array into an instance of your class:
List<Object[]> rows = query.getResultList();
List<MyObject> result = new ArrayList<>(rows.size());
for (Object[] row : rows) {
result.add(new MyObject((String) row[0],
(Long) row[1],
...));
}
Upvotes: 26