2009-09-11 8 views
6

betrachtet TabelleKarte Entitätsabfrage in Hibernate

sales (id, seller_id, amount, date) 

und hier eine Ansicht ist, die von sales erzeugt wird Abfrage mit SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id

total_sales (seller_id, amount) 

ich eine Einheit für einen Gesamtumsatz machen will, aber ohne die Blick auf die sql Seite.

Diese Entität wird aus einer Abfrage erstellt. Das nächste, was ich gefunden habe, ist this, aber ich konnte es nicht funktionieren lassen.

Auch wenn ich den Loader definiere, sucht Hibernate nach der Tabelle der Entität und gibt einen Fehler aus, wenn sie nicht gefunden werden kann. Wenn ich die Tabelle erzeuge, lädt sie die Entität nicht aus der angegebenen Abfrage, die ich definiert habe, Hibernate generiert die Abfrage selbst.

Gibt es eine Möglichkeit, @Loader zum Laufen zu bringen, oder gibt es eine andere Möglichkeit, eine Abfrage zu Entitäten zuzuordnen?

+1

Sie können 'session.createCriteria (TotalSales.class)' nicht über einen benutzerdefinierten Loader ausführen. Sie können es nicht als Entität abbilden (und auch nicht), ohne ein unterstützendes Objekt (Tabelle oder Sicht) in der Datenbank zu haben. – ChssPly76

Antwort

18

Warum verwenden Sie nicht einfach new in der Abfrage?

Sie schreiben eine Klasse TotalSales mit einem Konstruktor, der die seller_id und eine Ganzzahl verwendet.


bearbeiten: Wenn Kriterien API verwenden, können Sie die Verwendung AliasToBeanResultTransformer (siehe API docs). Er kopiert jeden Aliasnamen in eine gleichnamige Eigenschaft.

List list = s.createCriteria(Sales.class) 
    .setProjection(Projections.projectionList() 
    .add(Projections.property("id"), "SellerId") 
    .add(Projections.rowCount("id"), "Count")) 
    .setResultTransformer( 
    new AliasToBeanResultTransformer(TotalSales.class)) 
    .list(); 

Dann wird Ihr TotalSales braucht eine SellerId und Count Eigenschaft.

+0

+1 für eine gute erste Antwort. – KLE

+0

Da ich die neue Entität wie 'session.createCriteria (TotalSale.class) .list()' – nimcap

+0

hinzufügen möchte, fügte einen Abschnitt zu meiner Antwort für Kriterien hinzu. –

0

Neben Stefan Antwort, man könnte auch eine explizite HQL Abfrage

SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id 

Das Ergebnis natürlich gespeichert in List verwenden. Wenn dieser Datentyp ist für Sie nicht geeignet, Sie konnte:

  • schaffen neue TotalSale Objekte mit ihnen (Stefan Antwort verwenden wäre besser, wahrscheinlich)
  • eine Karte erstellen, um die Daten zu speichern (Sie können auch diese einbetten direkt in die Anfrage).
0

Sie können versuchen, einen benutzerdefinierten Lader zu definieren. Ich habe das nie benutzt, aber es scheint vernünftig zu sein:

<sql-query name="totalSale"> 
    <return alias="ts" class="TotalSale" /> 
    SELECT seller_id as {ts.seller_id}, SUM(amount) as ts.amount 
    FROM sales 
    WHERE seller_id = ? 
    GROUP BY seller_id 
</sql-query> 

Nicht sicher, ob der Filter auf seller_id benötigt wird.

Sie verweisen auf diese benannte Abfrage in einer Klasse-Mapping:

<class name="TotalSale"> 
    <id name="seller_id"> 
     <generator class="increment"/> 
    </id> 
    <property name="seller_id" /> 
    <property name="amount" /> 
    <loader query-ref="totalSale"/> 
</class> 

Es more details in the manual sind.

Alternativ können Sie direkt eine Namensabfrage aus dem Code verwenden. Auf diese Weise benötigen Sie keine Zuordnung von TotalSale und müssen die Abfrage nicht in den Code schreiben. Benannte Abfragen können auch Objekte zurückgeben. Siehe details about named queries in der Dokumentation.

+0

Dies wird in keiner Weise mit 'session.createCriteria()' helfen. – ChssPly76

+0

Ich bezweifle, dass createCriteria in diesem Fall dringend benötigt wird, deshalb schlage ich alternative Ansätze vor. –

+0

Ja, und ich habe deine andere Antwort neu gewählt. – ChssPly76

0

, wenn Sie wirklich eine bestimmte Einheit wollen nur für diesen Job Sie eine ‚Formel‘ auf einer benutzerdefinierten Eigenschaft verwenden können

<class name="SellerSales" table="Sales" lazy="true"> 
    <id name="SellerId" column="SellerId" type="int"> 
     <generator class="native" /> 
    </id> 
    <property name="SalesSum" type="float" update="false" insert="false" 
      formula="select SUM(sal.ammount) from sales sal where sal.seller_id = SellerId)" /> 
</class> 

public class SellerSales 
{ 
    public int SellerId {get; set;} 
    public float SalesSum {get; set;} 
} 

als solche seine accesible den Kriterien Motor für auftrags durch die Beschränkungen usw., die i denke, ist der Grund, warum Sie es für verwenden möchten.

+0

Dies funktioniert nicht, wenn die Tabelle "Seller" nicht existiert und AND keiner anderen Entität zugeordnet ist. Und wenn das der Fall ist, ist der ganze Punkt strittig. – ChssPly76

+0

eigentlich habe ich einen Mist-Top Fehler in der Post, der einzige Grund, warum ich gepostet habe, ist vielleicht der Themen-Starter bekommt eine Idee oder bietet einige Informationen darüber, was er wirklich braucht. sonst scheint Stefans Antwort richtig zu sein – Jaguar