2

Playframeworkのバージョンは1.2.xで、query.ResultListをVOに変換したい。

以下のように Part エンティティ Bean を作成しました。

@Entity
@Table(name="evaluation_part")
public class Part extends Model {

    public String name;  

    public String collegeName;

    public int peopleNum;
}

データ:

id     name     collegeName      peopleNum

1      Jsj1     JJJJ              32
2      Jsj2     JJJJ              23
3      Jsj3     JJJJ              32
4      Tjb1     TTTT              11
5      Tjb2     TTTT              14
6      Tjb3     TTTT              16

私の値オブジェクトクラス:

public class PartVO {

    public String collegeName;

    public int peopleNum;

}

そして、ネイティブ クエリを使用して結果を取得したいと考えています。

String sql="select collegeName,SUM(peopleNum) as peopleNum from evaluation_part group by collegeName";

クエリ結果は次のとおりです。

      collegeName      peopleNum

        TTTT              41
        JJJJ              87

やってみた:</p>

String sql="select collegeName,SUM(peopleNum) as peopleNum from evaluation_part group by collegeName";

Query query =JPA.em().createNativeQuery(sql);

List<PartVO> partVOs = query.getResultList();
for(int i=0;i<partVOs.size();i++) {      
    System.out.println(partVOs.get(i).collegeName);
}

次のエラーは私が得ているものです

ClassCastException occured : [Ljava.lang.Object; cannot be cast to valueobject.PartVO
4

3 に答える 3

2

そのために生のSQLを使用する必要はありません。hql では、新しい演算子を使用して VO を作成できます ( http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-selectを参照) 。

partVO クラスで 2 つの引数のコンストラクターを定義する必要があります。

select new package.PartVO(collegeName, SUM(peopleNum)) from Part group by collegeName
于 2012-08-29T06:33:06.000 に答える
0

結果インスタンスのクラスも引数として受け入れるバージョンのcreateNativeQuery(...)メソッドを使用できます。

http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#createNativeQuery(java.lang.String、java.lang.Class)。

ただし、Play FrameworkはAPIの実装でJPAのすべての機能を実装しているわけではないため、これが実際に機能することを確認してください。

于 2012-08-29T06:39:59.207 に答える
0

ソリューション 1: オブジェクトを Part.Hibernate に変換できる HQL で 'select new Part()' (Part クラスで定義されたコンストラクター) のみを使用し、リフレクションを使用して必要なすべてのフィールドを自動的に挿入します。

解決策 2:ここでは、配列のインデックスによってデータベースからフェッチされたレコードのすべてのフィールドを取得できるように、返される結果の型は Object[] でなければなりません。

solution1 と solution2 の違い: 以前はクエリでコンストラクターを使用し、後でレコードを Object[] に変換します。

あなたの場合、エンティティ間の複雑な関係を無視してください。上記の解決策が機能します。

ここで参照されたコード:

package controllers;

import play.*;
import play.db.jpa.JPA;
import play.mvc.*;
import java.util.*;

import models.*;

/**
* This demo is intended for fetching data from MYSQL.
* @author dhl@oopsplay.org
*/

public class Application extends Controller {

public static void index() {
    render();
}

/**
 * Prepare some data to test.
 */
public static void addPart() {

    //Add a part record to database.
    Part newPart=new Part("software","zjut",8).save();
    if(newPart.isPersistent()){
        renderText("Add successfully,there are %s records in the \'evaluation_part\' table.For convenience,please click the back button in the browser to go back previous page.",Part.count());
    }
}

/**
 * Fetch part entities from database;
 */
public static void fetchPart() {

    //-------------------Solution 1-------------------
    //[Pay attention]:Only use 'select new Part()'(constructor defined in the Part class) in the query that u can  convert object to Part.
    //Hibernate use reflection to automatically inject all the fields u need.
    List<Part> parts1=JPA.em().createQuery("select new Part(name,collegeName,peopleNum) from Part").getResultList();

    //For convenience, i output the detail in the console, focus on the change there.
    Logger.info("The name of first record is :%s", parts1.get(0).name);

    //-------------------Solution 2-------------------
    //[Pay attention]:Here the returned type of result must be Object[],so that u can got every field of the record fetched from database;
    List<Object[]> parts2=JPA.em().createNativeQuery("select name,collegeName,peopleNum from evaluation_part").getResultList();
    Logger.info("The name of first record is :%s", parts2.get(0)[0]);

    for(int i=0;i<parts2.size();i++){

        //The difference between solution1 and solution2:the previous use constructor in the query and the later transform a record into Object[].
        Logger.info("Name from parts1 is: %s", parts1.get(i).name);
        Logger.info("Name from parts2 is: %s", parts2.get(i)[0]);
    }

    renderText("There are %s record in the \'evaluation_part\' table",parts2.size());
}

}

于 2012-08-30T11:31:24.957 に答える