简体   繁体   中英

Map SQL query with multiple repetitions to hibernate entity

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM