2013-05-15 18 views
6

私の基準にGROUP BYを使用しようとしています。私はこれを実行する必要があります。Hibernateの基準GROUP BYとRETURN ENTITY LISTの使用

SELECT b FROM Book b GROUP BY volumeCode; 

私は次のコードしている:

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

をしかし、この基準は唯一volumeCode S(文字列のリスト)を返します。私はBookのリストを取得する必要があります。そこで、トランスフォーマーを使用しようとしました。

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(); 

このコードはnull値のリストを返します。基準でそれを行うことは可能ですか?

答えて

5

まず、プロジェクションはデータの量をフィルタリングします。データをさらに必要とする場合は、これらのプロパティも投影に追加する必要があります。

例:変圧器は、それが「ビーンに別名」言うことありません

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

は、それはあなたのJavaの豆「Book.java」の特性とエイリアスの試合を行います。

編集:変圧器なし

、投影は複数のプロパティを持っている場合、結果は次のように出てくる:

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 
} 

あなたは変圧器については、キャスト例外を取得したThatsなぜ、すべてのエイリアスをJava Beanのプロパティ名と照合してみてください。

+0

こんにちはZiul、あなたの返信のthx。あなたのアドバイスでは、オブジェクトのリストを取得しますが、リストからオブジェクトへのキャストを試みると、Javaは例外をスローします。 –

+0

Ehm、私は変圧器で線を削除するO: - )...この行を追加した後、私はまだnullオブジェクトのリストを取得します。 –

+0

あなたの投稿を編集していただきありがとうございます。私は1つのプロパティだけを取得するのではなく、オブジェクト全体を取得します。私は 'SELECT b FROM Book b GROUP BY volumeCode'を呼んだ後に同じ結果を得る必要があります。結果はListでなければなりません。

2

私はあなたが使用することができると思う:criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

+0

あなたは思いますか?どうして?どうやって? – rayryeng

+1

@rayryeng 'SELECT p FROM person p GROUP BY personId'を基準を使って取得しようとしたときと同じ問題が発生しましたが、setProjectionを使用すると' select distint(personId)from person'のsqlに相当するものに変換され、personId wheres i personオブジェクト全体を必要とします。リスト list = session.createCriteria( "Person"、 "p") .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); '人物オブジェクトのリストを返します。なぜ、どのようにこれが助けてくれるのかについて[ここ](http://stackoverflow.com/questions/10961048/setresulttransformer-in-criteria) – Mazrul

+0

あなたの記事にこれを追加してください。なぜこれが最初にあなたを助けたのかわからなかった – rayryeng

3

cz_Nesh。 私の最初の答えについて申し訳ありません。 私はHibernate APIを読んで、Hibernateのソースコードを読んでいます。 このコード

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

を使用している場合、それはリストEmpUserImplを返します。 このコード

 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(); 

を使用している場合、それはEmpUserImpl理由をリストしていない、リストを返しますか? 基準の親クラスCriteriaSpecificationを見れば分かります。

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(); 

}

あなたはのpublic static final ResultTransformer投影を見ることができますか?結果トランスフォーマが、 "ROOT_ENTITY"から "PROJECTION"に変更されているため、結果セットのトランスフォーマがsetProjection()を呼び出すことによって暗黙的に選択されていると言います。 はcriteria.setProjectionを使用すると意味があり、結果はEmpUserImplを表示しません。 select name、oid ..のように)。 List EmpUserImplを返すには、Projections.property( "name")。as( "name")を設定する必要があります。 これは私のコードです。

 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()); 
    } 

でも動作します。それがあなたを助けることを願っています。