08.12.2010

Quick & Dirty - JPA Native Queries und die Ergebnismenge

Ein Problem beim Absetzen von nativen Queries ist die unkomplizierte komplizierte Verarbeitung der Ergebnisse. Anstatt durch ein Array von Objekten zu iterieren wäre es ja durchaus wünschenswert, wenn man die Ergebnisse der Query direkt in eine zugehörige Bean transportieren kann.
Leider ist mit der Annotation @SqlResultSetMapping nur ein Mappen von Entitäten möglich, aber nicht von einfachen Beans, die für einen Datenaustausch oder eine Visualisierung innerhalb der GUI benötigt werden.

Um diesem Problem aus dem Weg zu gehen, habe ich einen kleinen Mapper erstellt, der es ermöglicht aus einer Liste, welche die Ergebnisse der Query in Arrays von Objekten enthält, eine Liste der gewünschten Beans erzeugt.


  1. An dieser Stelle werden die entsprechenden Klassen der Objekte ausgelesen und in ein Array gesteckt. Dies ist notwendig, damit man im zweiten Schritt mit Hilfe der Java Reflection API nach einem zugehörigen Konstruktor schauen kann.
  2. Suche nach dem Konstruktor mit der zugehörigen Signatur, die durch die Liste der Spalten innerhalb der Ergebnismenge definiert ist.
  3. Erstellen der entsprechenden Beans und hinzufügen zur Liste der Ergebnisse.
Narrensicher ist die Art der Konvertierung nicht. Die Konvertierung basiert im wesentlichen auf der Annahme, dass die Arrays innerhalb des Result Set grundsätzlich gleich sind und keine null-Werte enthalten sind. Sollte also jemand Verbesserungen bzw. Anregungen haben, dann immer her damit.

Da dies nur funktioniert, wenn die Liste der Ergebnisse mehrere Spalten enthält, habe ich gleichtzeitig noch eine Methode erstellt, die den unwahrscheinlichen Fall abdeckt, dass eine einzelne Spalte in eine Bean gesteckt werden soll. Daher der Vollständigkeit halber auch diese Methode als Screenshot.

Kommentare:

  1. Das Problem stellt sich so eigentlich nicht mit
    "SELECT NEW constructor_expr" lassen sich sehr viele DTOs bauen.

    Zum Beispiel:
    "SELECT NEW my.ui.DTO(p.name, p.surname) FROM Person p".

    Ist ein alter Hut, ging schon mit JPA 1.

    Viele Grüße

    Florian

    AntwortenLöschen
  2. Hallo Florian,

    es ist richtig, dass dies bereits mit JPA 1 ging. Dieser Artikel beschäftigt sich allerdings mit dem Mapping von _nativen_ Queries, nicht mit dem Mapping von Ergebnissen aus JPQL Queries.

    Die von dir erwähnte Lösung findet sich in dem Artikel zu den JPA Constructor Expressions:

    http://saschadoemer.blogspot.com/2010/12/quick-dirty-jpa-constructor-expressions.html

    So alt ist der Hut also dann doch wieder nicht ;-)

    Gruß

    Sascha

    AntwortenLöschen