2016-03-31 22 views
27

Spring Data JPAを使用してSpringBootアプリケーションを開発しています。私はいくつかのフィールドでグループ化し、カウントを取得するカスタムJPQLクエリを使用しています。以下は私のリポジトリメソッドです。Spring Data JPA GROUP BYクエリからカスタムオブジェクトを返す方法

@Query(value = "select count(v) as cnt, v.answer from Survey v group by v.answer") 
public List<?> findSurveyCount(); 

それが働いていると、次のように結果が得られた:どのように私はこれを達成することができます

[ 
    { "cnt":1, "answer":"a1" }, 
    { "cnt":2, "answer":"a2" } 
] 

[ 
    [1, "a1"], 
    [2, "a2"] 
] 

私はこのような何かを取得したいのでしょうか?

答えて

61

ステップ1:シンプルなBeanクラスを宣言

package com.path.to.class; 

public class SurveyAnswerStatistics { 
    private String answer; 
    private Long cnt; 

    public SurveyAnswerStatistics(String answer, Long cnt) { 
    this.answer = answer; 
    this.count = cnt; 
    } 
} 

ステップ2:リターン豆レポからのインスタンスsitory方法

@Query("SELECT " + 
     " new com.path.to.class.SurveyAnswerStatistics(v.answer, count(v)) " + 
     "FROM " + 
     " Survey v " + 
     "GROUP BY " + 
     " v.answer") 
List<SurveyAnswerStatistics> findSurveyCount(); 
+1

それは動作していません、発射エラー: '原因:java.lang.IllegalArgumentException:org.hibernate.hql.internal.ast.QuerySyntaxException:Unable [SurveyAnswerReport]クラスの検索[com.furniturepool.domain.Survey v group by v.answer]から新しいSurveyAnswerReport(v.answer、count(v.id))を選択する \t at org.hibernate.jpa.spi.AbstractEntityManagerImpl。コンバート(AbstractEntityManagerImpl.java:1750) \t at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) \t at org.hibernate.jpa.spi.AbstractEnti ......... .' –

+0

あなたの出力にあるこの「SurveyAnswerReport」とは何ですか? 'SurveyAnswerStatistics'を自分のクラス' SurveyAnswerReport'に置き換えたと仮定します。完全修飾クラス名を指定する必要があります。 – Bunti

+7

Beanクラスは完全修飾されている必要があります。つまり、完全なパッケージ名を含める必要があります。 'com.domain.dto.SurveyAnswerReport'のようなものです。 – manish

5

このSQLクエリは、リスト<オブジェクト[]>を返します。

あなたはこのようにそれを行うことができます。

@RestController 
@RequestMapping("/survey") 
public class SurveyController { 

    @Autowired 
    private SurveyRepository surveyRepository; 

    @RequestMapping(value = "/find", method = RequestMethod.GET) 
    public Map<Long,String> findSurvey(){ 
     List<Object[]> result = surveyRepository.findSurveyCount(); 
     Map<Long,String> map = null; 
     if(result != null && !result.isEmpty()){ 
      map = new HashMap<Long,String>(); 
      for (Object[] object : result) { 
      map.put(((Long)object[0]),object[1]); 
      } 
     } 
    return map; 
    } 
} 
+1

ご回答ありがとうございます。 –

+1

この質問に対するお返事ありがとうございます。それは鮮明で明確です –

+0

@PranavCBalanありがとうございました:) – ozgur

1

、sureveyQueryAnalyticsを言うと、私はこれが古い質問ですけど、それはすでに回答されているクエリが

カスタムPOJOクラスに値を返さ
@Query(value = "select new com.xxx.xxx.class.SureveyQueryAnalytics(s.answer, count(sv)) from Survey s group by s.answer") 
List<SureveyQueryAnalytics> calculateSurveyCount(); 
5

を保存するカスタムPOJOクラスを定義しますしかし別のアプローチがあります:

@Query("select new map(count(v) as cnt, v.answer) from Survey v group by v.answer") 
public List<?> findSurveyCount(); 
0

私はクエリー文字列のjava型名が好きではなく、特定のコンストラクトctor:

@Query("SELECT v.answer as "+PROP_ANSWER+", count(v) as "+PROP_CNT+" FROM Survey v GROUP BY v.answer") 

public class SurveyAnswerStatistics { 
    public static final String PROP_ANSWER = "answer"; 
    public static final String PROP_CNT = "cnt"; 

    private String answer; 
    private Long cnt; 

    public SurveyAnswerStatistics(HashMap<String, Object> values) { 
    this.answer = (String) values.get(PROP_ANSWER); 
    this.count = (Long) values.get(PROP_CNT); 
    } 
} 
関連する問題