it-swarm.com.de

Wie ordne ich die Ergebnisse einer SQL-Abfrage mit Hibernate am besten einem Java-Objekt zu, das keine Entität ist?

Ich habe eine im Ruhezustand verwaltete Java-Entität namens X und eine native SQL-Funktion (myfunc), die ich aus einer Hibernate-SQL-Abfrage heraus aufrufe:

SQLQuery q = hibernateSession.createSQLQuery(
                     "SELECT *, myfunc(:param) as result from X_table_name"
             );

Ich möchte das Ergebnis dieser Abfrage einer Klasse zuordnen (die nicht unbedingt von Hibernate verwaltet wird) mit dem Namen Y. Y sollte alle Eigenschaften/Felder von X sowie die von result zurückgegebene myfunc enthalten, z. Y könnte die Klasse X erweitern und ein "Ergebnis" -Feld hinzufügen.

Was ich versucht habe:

  1. Ich habe versucht, q.addEntity(Y.class) zu verwenden, aber dies schlägt fehl mit: org.hibernate.MappingException: Unknown entity com.mycompany.Y
  2. q.setResultTransformer(Transformers.aliasToBean(Y.class)); aber dies schlägt fehl mit: org.hibernate.PropertyNotFoundException: Could not find setter for some_property. X hat ein Feld namens someProperty mit dem entsprechenden Getter und Setter, aber in diesem Fall scheint es nicht so, als würde Hibernate den Spaltennamen (some_property) dem richtigen Feldnamen zuordnen.
  3. q.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); gibt eine Map zurück, aber die Werte entsprechen nicht immer dem Typ, den das entsprechende Feld in X erwartet. Beispielsweise können Felder in X vom Typ enum und Date nicht direkt aus der Map zugeordnet werden, die von der SQL-Abfrage zurückgegeben wird (bei der es sich um Strings handelt).

Wie kann man mit dieser Situation umgehen?

17
Johan

Siehe das Kapitel der Dokumentation zu SQL-Abfragen .

Mit der addScalar()-Methode können Sie angeben, welchen Typ Hibernat für eine bestimmte Spalte verwenden soll.

Und Sie können Aliase verwenden, um die Ergebnisse mit den Bean-Eigenschaften abzubilden:

select t.some_property as someProperty, ..., myfunc(:param) as result from X_table_name t

Oder (und obwohl einige Codezeilen erforderlich sind, ist dies meine bevorzugte Lösung), können Sie die Zuordnung einfach selbst vornehmen:

List<Object[]> rows = query.list();
for (Object[] row : rows) {
    Foo foo = new Foo((Long) row[0], (String) row[1], ...);
}

Dadurch werden Reflexionen vermieden und Sie können alles steuern.

16
JB Nizet

Einfach. Die Zeilen in Map<String, Object> umwandeln: 

final org.hibernate.Query q = session.createSQLQuery(sql);
q.setParameter("geo", geo);
q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
final List<Map<String, Object>> src = q.list();
final List<VideoEntry> results = new ArrayList<VideoEntry>(src.size());
for (final Map<String, Object> map:src) {
    final VideoEntry entry = new VideoEntry();
    BeanUtils.populate(entry, map);
    results.add(entry);
}
7
Stan Sokolov

Zunächst müssen Sie die Entität in der XML-Datei für den Ruhezustand der Konfiguration wie folgt deklarieren: ..... Class = "Pfad zu Ihrer Entität"

Oder Sie können dasselbe programmgesteuert ausführen, bevor Sie die Abfrage durchführen.

0
Popa Andrei