一見簡単な問題があります。
entityManager()
.createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla")
そして、私は次のようにPOJOに選択結果を書き込みたいです:
public class AggregateStatsDto {
private int total;
private long totalSum;
// getters, setters, cosntructors
}
これを達成するための最良の方法は何ですか?
私はJPA 2.1を使用できます@ SqlResultSetMappingを@ ConstructorResultと組み合わせて使用しようとしました:
@SqlResultSetMapping(name = "AggregateStatsResult", classes = {
@ConstructorResult(targetClass = AggregateStatsDto.class,
columns = {
@ColumnResult(name = "total"),
@ColumnResult(name = "totalSum")
})
})
public class AggregateStatsDto {
private long total;
private int totalSum;
// getters, setters, cosntructors
}
クエリ:
AggregateStatsDto result = (AggregateStatsDto) entityManager()
.createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla", "AggregateStatsResult")
.getSingleResult();
しかし、運はありません。とにかく@Entityが欲しいようです。しかし、POJOだけが欲しいのです。
org.hibernate.MappingException: Unknown SqlResultSetMapping [AggregateStatsResult]"
前もって感謝します!
私は次の方法で問題を解決しました:これはクエリです:
final Query query = Sale.entityManager().createNativeQuery(...);
次に、エンティティマネージャー内の内部Hibernateセッションにアクセスし、スカラー/ resultTransformerを適用しました。それで全部です!
// access to internal Hibernate of EntityManager
query.unwrap(SQLQuery.class)
.addScalar("total", LongType.INSTANCE)
.addScalar("amountOfSales", LongType.INSTANCE)
.addScalar("amountOfProducts", LongType.INSTANCE)
.setResultTransformer(Transformers.aliasToBean(SaleStatsInfo.class));
...
query.getSingleResult();
@SqlResultSetMappingアノテーションを、DTOクラスではなく、実際のエンティティであるクラスに配置します。非エンティティでSqlResultSetMappingに注釈を付けると、エンティティマネージャはマッピングを検出できません。
@SqlResultSetMapping(name = "AggregateStatsResult", classes = {
@ConstructorResult(targetClass = AggregateStatsDto.class,
columns = {
@ColumnResult(name = "total"),
@ColumnResult(name = "totalSum")
})
})
@Entity
public class SomeOtherClassWhichIsAnEntity {
これは推奨される方法ではありません。より効率的な方法は上記の@SqlResultSetMappingで説明されていますが、よりハードコアなものが必要な場合は、エンティティマネージャーが返すオブジェクトによってエンティティマネージャーの結果にアクセスできます。
例えば :
_ Query q = getEntityManager().createNativeQuery(queryString);
_
q.getSingleResult();
bringを使用してそれをトリガーすると、_Java.util.HashMap
_型のオブジェクトを使用して、行ごとに結果にアクセスできます。
例えば:
_ Query q = getEntityManager().createNativeQuery(queryString);
Java.util.HashMap res = (Java.util.HashMap) q.getSingleResult();
for (Object key : res.keySet()) {
System.out.println(key.toString());
System.out.println( res.get(key).toString());
}
_