2013-05-15 8 views
6

Ich versuche GROUP BY in meinen Kriterien zu verwenden. Ich brauche dies zu tun:Hibernate-Kriterien Verwenden von GROUP BY und RETURN ENTITY LIST

SELECT b FROM Book b GROUP BY volumeCode; 

Ich habe folgenden Code:

Criteria c = s.createCriteria(Book.class); 
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode"))); 
    List<Book> result = c.list(); 

Aber diese Kriterien gibt nur volumeCode s (eine Liste von Strings). Ich brauche eine Liste von Book s. So versuchte ich Transformers zu verwenden:

Criteria c = s.createCriteria(Book.class); 
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode"))); 
    c.setResultTransformer(Transformers.aliasToBean(Book.class)); 
    List<Book> result = c.list(); 

Dieser Code gibt eine Liste der Nullwerte zurück. Ist es möglich, dies mit Kriterien zu tun?

Antwort

5

Zuerst filtert das Projekt die Menge der abgerufenen Daten, wenn Sie mehr Daten möchten, sollten Sie diese Eigenschaften auch zur Projektion hinzufügen.

Beispiel:

c.setProjection(Projections.projectionList() 
    .add(Projections.property("id").as("id")) 
    .add(Projections.property("descripction").as("description")) 
    .add(Projections.groupProperty("volumeCode").as("volumeCode"))); 

Nun wird der Transformator das tut, was er sagt, "Alias ​​zu Bean", tut es ein Alias ​​Spiel mit den Eigenschaften Ihres Java Bean "Book.java".

Edit:

Ohne den Transformator, wenn der Vorsprung mehr als eine Eigenschaft hat, kommt das Ergebnis wie folgt aus:

for(Object[] item:criteria.list()){ 
    System.out.println((String)item[0]); //ID 
    System.out.println((String)item[1]); //Description 
    System.out.println((String)item[2]); //Volume code 
} 

Das ist, warum wurden Sie die Besetzung Ausnahme bekommen, über den Transformator, Versuchen Sie, jeden Alias ​​mit dem Eigenschaftsnamen Ihrer Java-Bean abzugleichen.

+0

Hallo Ziul, thx für Ihre Antwort. Mit Ihrem Rat bekomme ich Liste der Objekte, aber Java löst Exception aus, wenn ich versuche, ein beliebiges Objekt aus der Liste in das Buch zu schreiben. –

+0

Ehm, ich lösche Zeile mit Transformer O: -) ... Nach dem Hinzufügen dieser Zeile bekomme ich noch eine Liste von Null-Objekten. –

+0

Vielen Dank für die Bearbeitung Ihres Posts. Ich will nicht nur eine Eigenschaft, sondern das ganze Objekt bekommen. Ich brauche die gleiche Liste von Objekten wie nach dem Aufruf 'SELECT b FROM Buch b GROUP BY volumeCode', so dass das Ergebnis sein sollte Liste

2

Ich glaube, Sie verwenden können: criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

+0

Sie denken? Warum? Wie? – rayryeng

+1

@rayryeng Ich stoße auf das selbe Problem und versuche, 'SELECT p FROM Person p GROUP BY personId' zu erhalten, benutze aber setProjection, um es in sql Äquivalent von' select distint (personId) von Person 'umzuwandeln und return list of personId wheres i brauche die ganze Person Objekt und 'Liste list = session.createCriteria (" Person "," p ") .setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY);' zurück die Liste der Person Objekt. wie für warum und wie hoffe das hilft [hier] (http://stackoverflow.com/questions/10961048/setresulttransformer-in-criteria) – Mazrul

+0

Fügen Sie dies zu Ihrem Beitrag hinzu. Wir wussten nicht, warum dir das anfangs geholfen hat – rayryeng

3

cz_Nesh. Entschuldigung wegen meiner ersten Antwort. Ich lese Hibernate API und lese einige Hibernate Quellcode ich finde das. wenn Sie diesen Code verwenden

session.createCriteria(EmpUserImpl.class).list(); 

es wird Liste EmpUserImpl zurück. wenn Sie diesen Code verwenden

 criteria.setProjection(Projections.projectionList() 
      .add(Projections.groupProperty("company").as("company")) 
      .add(Projections.property("name").as("name")) 
      .add(Projections.property("company").as("company"))); 
     List list = criteria.list(); 

wird Liste zurückkehren, Liste ist nicht EmpUserImpl warum? Ich sehe die Elternklasse des Kriteriums CriteriaSpecification ich finde das.

public interface CriteriaSpecification { 

/** 
* The alias that refers to the "root" entity of the criteria query. 
*/ 
public static final String ROOT_ALIAS = "this"; 

/** 
* Each row of results is a <tt>Map</tt> from alias to entity instance 
*/ 
public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE; 

/** 
* Each row of results is an instance of the root entity 
*/ 
public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE; 

/** 
* Each row of results is a distinct instance of the root entity 
*/ 
public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE; 

/** 
* This result transformer is selected implicitly by calling <tt>setProjection()</tt> 
*/ 
public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE; 

/** 
* Specifies joining to an entity based on an inner join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#INNER_JOIN} 
*/ 
@Deprecated 
public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue(); 

/** 
* Specifies joining to an entity based on a full join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#FULL_JOIN} 
*/ 
@Deprecated 
public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue(); 

/** 
* Specifies joining to an entity based on a left outer join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN} 
*/ 
@Deprecated 
public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue(); 

}

können Sie sehen, die public static final ResultTransformer PROJECTION? es besagt, dass dieser Ergebnistransformator implizit durch Aufruf von setProjection() ausgewählt wird ist der Mittelwert, wenn Sie criteria.setProjection verwenden, wird das Ergebnis nicht EmpUserImpl auflisten, da ResultTransformer in "PROJECTION" von "ROOT_ENTITY" geändert wird. wie wähle Namen, oid ..). Wenn Sie also List EmpUserImpl zurückgeben möchten, müssen Sie Projections.property ("name"). As ("name")., (Wenn Sie einen Namen brauchen, setzen Sie den Namen). das ist mein Code.

 Criteria criteria = session.createCriteria(EmpUserImpl.class); 
    criteria.setProjection(Projections.projectionList() 
      .add(Projections.groupProperty("company").as("company")) 
      .add(Projections.property("name").as("name")) 
      .add(Projections.property("company").as("company"))); 
    criteria.setResultTransformer(Transformers.aliasToBean(EmpUserImpl.class)); 
    List<EmpUserImpl> list = criteria.list(); 
    for (EmpUserImpl empUserImpl : list) { 
     System.out.println(empUserImpl.getName()); 
    } 

kann es funktionieren. Ich hoffe, es kann dir helfen.