2010-05-28 9 views
5

Ich bin gerade dabei, JPA in einer einfachen Java-Webanwendung, die auf Glassfish 3 ausgeführt wird (Persistenzprovider ist EclipseLink), in den Griff zu bekommen. Bis jetzt, ich mag es wirklich (Bugs in Netbeans/Glassfish Interaktion beiseite), aber es gibt etwas, dass ich tun können, dass ich nicht sicher bin, wie es geht.JPA - Einstellung Entity-Klassen-Eigenschaft aus berechneter Spalte?

Ich habe eine Entitätsklasse (Artikel), die einer Datenbanktabelle (Artikel) zugeordnet ist. Ich versuche, eine Abfrage für die Datenbank auszuführen, die eine berechnete Spalte zurückgibt, aber ich kann nicht herausfinden, wie eine Eigenschaft der Article-Klasse eingerichtet wird, damit die Eigenschaft beim Aufrufen der Abfrage vom Spaltenwert ausgefüllt wird.

Wenn ich eine reguläre "Select ID, Titel, Körper von Artikel" Abfrage, bekomme ich eine Liste von Artikel Objekte fein, mit der ID, Titel und Körper Eigenschaften gefüllt. Das funktioniert gut.

Allerdings, wenn ich die folgenden:

Query q = em.createNativeQuery("select id,title,shorttitle,datestamp,body,true as published, ts_headline(body,q,'ShortWord=0') as headline, type from articles,to_tsquery('english',?) as q where idxfti @@ q order by ts_rank(idxfti,q) desc",Article.class); 

(dies ist eine Volltext-Suche auf Postgres mit tsearch2 - es ist ein db-spezifische Funktion, so dass ich bin mit einem NativeQuery)

Sie kann sehen, dass ich eine berechnete Spalte, Überschrift genannt habe. Wie füge ich meiner Article-Klasse eine Überschrift-Eigenschaft hinzu, damit sie von dieser Abfrage ausgefüllt wird?

Bisher habe ich versucht, es auf @Transient zu setzen, aber das endet damit, dass es die ganze Zeit null ist.

Antwort

7

Es gibt wahrscheinlich keine gute Möglichkeiten, es zu tun, nur manuell:

Object[] r = (Object[]) em.createNativeQuery(
    "select id,title,shorttitle,datestamp,body,true as published, ts_headline(body,q,'ShortWord=0') as headline, type from articles,to_tsquery('english',?) as q where idxfti @@ q order by ts_rank(idxfti,q) desc","ArticleWithHeadline") 
    .setParameter(...).getSingleResult(); 

Article a = (Article) r[0]; 
a.setHeadline((String) r[1]); 

-

@Entity 
@SqlResultSetMapping(
    name = "ArticleWithHeadline", 
    entities = @EntityResult(entityClass = Article.class), 
    columns = @ColumnResult(name = "HEADLINE")) 
public class Article { 
    @Transient 
    private String headline; 
    ... 
} 
2

AFAIK, ist JPA nicht standardisierte Unterstützung bietet für berechnete Attribute. Mit Hibernate würde man einen Formula verwenden, aber EclipseLink hat kein direktes Äquivalent. James Sutherland machte einige Vorschläge in Re: Virtual columns (@Formula of Hibernate) aber:

Es gibt keine direkte Entsprechung (bitte Protokoll eine Erweiterung), aber je nach , was Sie tun wollen, gibt es Möglichkeiten, um das Gleiche erreichen.

Eclipse definiert eine TransformationMapping die einen berechneten Wert von mehreren Feld Werte abbilden, oder die Datenbank zugreifen.

Sie können die SQL für jede CRUD Operation für eine Klasse überschreiben, indem Sie den DeskriptorQueryManager des Deskriptors verwenden.

Sie konnten einen Blick auf Ihre Datenbank definieren, die anstelle der Tabelle auf die Ansicht, die die Funktion und Anfahrtsplan Ihre Entity führt.

Sie können auch geringfügige Übersetzungen mit Hilfe von Konvertern oder Eigenschaften Get/Set-Methoden durchführen.

haben auch einen Blick auf die enhancement request, die eine Lösung, die eine DescriptorEventListener in den Kommentaren unter Verwendung hat.

All dies ist natürlich kein Standard JPA.

Verwandte Themen