I have a result set that is returned from a pretty complex query which I would prefer to run using SQL rather than HQL. Just for context - It is a suggestions result set that suggest replacing existing objects that the customer pays for, to another type of objects that may cost less. So for each suggestion per product there are 3 columns that repeat themselves - id
, type
, price
and 2 different columns that represent a suggestion - new_type
and new_price
.
My result set looks something like this:
id type price new_type new_price
------------------------------------------------------
1 14 90 12 85
1 14 90 11 87
1 14 90 7 73
2 9 80 7 73
2 9 80 4 52
I would like to map it to a Java object that looks something like this
class Suggestion {
private Long id;
private Integer type;
private float price;
private List<Replacement> replacements;
private class Replacement {
private Integer type;
private float price;
// getters, setters, constructors removed
}
// getters, setters, constructors removed
}
I'm not sure if Hibernate offers this kind of transformer out of the box (couldn't find one). I'm also not sure that writing a new transformer is the way to go.
That's the solution I used in the meantime, I won't accept the answer in the hope of a better one:
public class SuggestionsTransformer implements ResultTransformer {
Map<String, Suggestions> suggestionsMap = new HashMap<>();
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
String id = (String) tuple[0];
String origType = (String) tuple [1];
float origPrice = (float) tuple[2];
String suggestedType = (String) tuple[3];
float suggestedPrice = (float) (tuple[4] == null ? 0.0f : tuple[4]);
Suggestions suggestions;
if(suggestionsMap.containsKey(id)) {
suggestions = suggestionsMap.get(id);
} else {
suggestions = new Suggestions();
suggestions.setId(id);
suggestions.setOrigType(origType);
suggestions.setOrigPrice(origPrice);
}
suggestions.addSavingSuggestion(suggestedType, suggestedPrice);
return suggestions;
}
@Override
public List transformList(final List list) {
// This method makes sure that each id returns only once
Set resultWithoutDuplications = new HashSet(list);
return new ArrayList(resultWithoutDuplications);
}
}
In my DAO (I'm using an entity manager):
Query query = entityManager.createNativeQuery("Some native SQL query here");
SQLQuery sqlQuery = query.unwrap(SQLQuery.class); // Query interface does not have setResultTransformer so instead you can unwrap and get the underlying instance of the sql query
sqlQuery.setResultTransformer(new UnderutilizedSuggestionsTransformer());
return new ArrayList<>(sqlQuery.list());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.