Java createNativeQuery 映射到 POJO(非实体)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26831893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
createNativeQuery mapping to POJO (non-entity)
提问by fasth
I have an easy problem at the first glance:
乍一看,我有一个简单的问题:
entityManager()
.createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla")
And I want to write select result into POJO, like this:
我想将选择结果写入 POJO,如下所示:
public class AggregateStatsDto {
private int total;
private long totalSum;
// getters, setters, cosntructors
}
What the best way to achieve this?
实现这一目标的最佳方法是什么?
I can use JPA 2.1 and tried to use @SqlResultSetMappingin conjuction with @ConstructorResult:
我可以使用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
}
Query:
询问:
AggregateStatsDto result = (AggregateStatsDto) entityManager()
.createNativeQuery("select count(*) as total, select sum(field) as total_sum ... blabla", "AggregateStatsResult")
.getSingleResult();
But no luck. It seems that it wants @Entity anyway. But I want just a POJO.
但没有运气。似乎无论如何它都想要@Entity。但我只想要一个 POJO。
org.hibernate.MappingException: Unknown SqlResultSetMapping [AggregateStatsResult]"
Thanks in advance!
提前致谢!
采纳答案by fasth
I resolved my problem in following way: This is a query:
我通过以下方式解决了我的问题:这是一个查询:
final Query query = Sale.entityManager().createNativeQuery(...);
Then I accessed to internal Hibernate session inside entity manager and applied scalars/resultTransformer. Thats all!
然后我访问了实体管理器内部的内部 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();
回答by Hannes
Hibernate will fill any pojo if you privide a propper constructor.
如果您提供一个合适的构造函数,Hibernate 将填充任何 pojo。
select new Pojo(p1, p2, p3,...) from entity)
select new Pojo(p1, p2, p3,...) from entity)
will return a list of Pojo instances.
将返回 Pojo 实例的列表。
回答by jeff
Put your @SqlResultSetMapping annotation in a class which is an actual entity, not in the DTO Class. Your entity manager can not discover your mapping when you annotate a SqlResultSetMapping in a non-entity.
将您的 @SqlResultSetMapping 注释放在一个实际实体的类中,而不是放在 DTO 类中。当您在非实体中注释 SqlResultSetMapping 时,您的实体管理器无法发现您的映射。
@SqlResultSetMapping(name = "AggregateStatsResult", classes = {
@ConstructorResult(targetClass = AggregateStatsDto.class,
columns = {
@ColumnResult(name = "total"),
@ColumnResult(name = "totalSum")
})
})
@Entity
public class SomeOtherClassWhichIsAnEntity {
回答by goyalshub1509
I struggled a lot in this issue and finally a found a good solution.
我在这个问题上挣扎了很多,终于找到了一个很好的解决方案。
Situation: I have a native query and I am fetching only few fields or all fields from the database table or may be I also have some operations on columns while I am fetching data from table.
情况:我有一个本机查询,我只从数据库表中获取几个字段或所有字段,或者我在从表中获取数据时也对列进行了一些操作。
Now I want to map the output of this nativequery which we get using getResultList() method into a own POJO class/non-JPA class. The output of getResultList() is a list of objects i.e. List, so we need to manually loop through and set values into our bean/pojo class. Looks at the snippet below.
现在我想将我们使用 getResultList() 方法获得的这个 nativequery 的输出映射到一个自己的 POJO 类/非 JPA 类中。getResultList() 的输出是一个对象列表,即 List,因此我们需要手动循环并将值设置到我们的 bean/pojo 类中。看看下面的片段。
So my query is this -
所以我的查询是这样的 -
// This is your POJO/bean class where you have settter/getter
// methods of values you want to fetch from the database
List<YourPOJO> yourPOJOList = new ArrayList<YourPOJO>();
YourPOJO pojo = null;
StringBuffer SQL = new StringBuffer();
// I am creating some random SQL query
SQL.append("SELECT tb1.col1, ");
SQL.append(" tb1.col2, ");
SQL.append(" tb2.col3, ");
SQL.append("FROM Table1 tb1, Table2 tb2 ");
SQL.append("WHERE tb1.ID = tb2.ID ");
qry = getEntityManager().createNativeQuery(SQL.toString());
List<Object[]> cdList = qry.getResultList();
for(Object[] object : cdList){
pojo = new YourPojo();
// Here you manually obtain value from object and map to your pojo setters
pojo.setCode(object[0]!=null ? object[0].toString() : "");
pojo.setProductName(object[1]!=null ? object[1].toString() : "");
pojo.setSomeCode(object[2]!=null ? object[2].toString() : "");
yourPOJOList.add(pojo);
}
回答by AbstactVersion
This is not the suggested way . The more efficient way is mentioned above with @SqlResultSetMapping but in case you want something more hardcore you can access the Entity Manager's result by the object it returns .
这不是建议的方式。上面使用@SqlResultSetMapping 提到了更有效的方法,但如果您想要更核心的东西,您可以通过它返回的对象访问实体管理器的结果。
For instance :
例如 :
Query q = getEntityManager().createNativeQuery(queryString);
Trggering that with q.getSingleResult();
brings back to u an Object of type java.util.HashMap
which you can use to access your results row by row .
触发它 q.getSingleResult();
会给你带回一个类型的对象 java.util.HashMap
,你可以用它来逐行访问你的结果。
For instance:
例如:
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());
}