Java 使用5.2.10实现Hibernate本机查询

Java 使用5.2.10实现Hibernate本机查询,java,hibernate,Java,Hibernate,在Hibernate

在Hibernate<5.2下,可以使用如下通用SQL查询

String sql = "select a, b, sum (c) csum from a group by a, b";
SQLQuery q = session.createSqlQuery (sql);
q
    .addScalar ("a", IntegerType.INSTANCE)
    .addScalar ("b", IntegerType.INSTANCE)
    .addScalar ("csum", IntegerType.INSTANCE);
q.setResultTransformer (new AliasToBeanResultTransformer (RankingModel.class));
List<RankingModel> results = q.list ();
但是,在5.2中,
addScalar()
setResultTransformer()
都被弃用,建议改用
session.createNativeQuery()
。与上述内容最接近的等价物是:

String sql = "select a, b, sum (c) csum from a group by a, b";
NativeQuery<RankingModel> q = session.createNativeQuery (sql, RankingModel.class);
List<RankingModel> results = q.list ();
String sql=“按a,b从组中选择a,b,sum(c)csum”;
NativeQuery q=session.createNativeQuery(sql,RankingModel.class);
列表结果=q.List();
但是,此代码在以下情况下失败:

org.hibernate.MappingException: Unknown entity: ... RankingModel] with root cause
org.hibernate.MappingException: Unknown entity: ... RankingModel
    at org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:620)
    at org.hibernate.engine.spi.SessionFactoryImplementor.getEntityPersister(SessionFactoryImplementor.java:335)
    at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.getSQLLoadable(SQLQueryReturnProcessor.java:358)
    at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processRootReturn(SQLQueryReturnProcessor.java:411)
    at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processReturn(SQLQueryReturnProcessor.java:378)
    at org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.process(SQLQueryReturnProcessor.java:180)
    at org.hibernate.loader.custom.sql.SQLCustomQuery.<init>(SQLCustomQuery.java:71)
    at org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl.createQueryPlan(NativeQueryInterpreterStandardImpl.java:70)
    at org.hibernate.engine.query.spi.QueryPlanCache.getNativeSQLQueryPlan(QueryPlanCache.java:213)
    at org.hibernate.internal.AbstractSharedSessionContract.getNativeQueryPlan(AbstractSharedSessionContract.java:550)
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:992)
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:148)
org.hibernate.MappingException:未知实体:。。。具有根本原因的RankingModel]
org.hibernate.MappingException:未知实体:。。。兰金模型
位于org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:620)
位于org.hibernate.engine.spi.SessionFactoryImplementor.getEntityPersister(SessionFactoryImplementor.java:335)
位于org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.getSQLLoadable(SQLQueryReturnProcessor.java:358)
位于org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processRootReturn(SQLQueryReturnProcessor.java:411)
位于org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.processReturn(SQLQueryReturnProcessor.java:378)
位于org.hibernate.loader.custom.sql.SQLQueryReturnProcessor.process(SQLQueryReturnProcessor.java:180)
位于org.hibernate.loader.custom.sql.SQLCustomQuery.(SQLCustomQuery.java:71)
在org.hibernate.engine.query.internal.NativeQueryInterpreterStandardImpl.createQueryPlan(NativeQueryInterpreterStandardImpl.java:70)
位于org.hibernate.engine.query.spi.QueryPlanCache.getNativeSQLQueryPlan(QueryPlanCache.java:213)
位于org.hibernate.internal.AbstractSharedSessionContract.getNativeQueryPlan(AbstractSharedSessionContract.java:550)
位于org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:992)
位于org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:148)

有人知道我遗漏了什么吗?

您可以尝试使用

String sql = "select a, b, sum (c) csum from a group by a, b";
NativeQuery<?> q = session.createNativeQuery (sql);
List<RankingModel> results = (List<RankingModel>)q.list ();
String sql=“按a,b从组中选择a,b,sum(c)csum”;
NativeQuery q=session.createNativeQuery(sql);
列表结果=(List)q.List();
它将工作,但在IDE中它将抛出警告

String sql=“按a,b从组中选择a,b,sum(c)csum”;
NativeQuery q=session.createNativeQuery(sql).addSynchronizedEntityClass(RankingModel.class);
列表结果=(List)q.List();
String sql=“按a,b从组中选择a,b,sum(c)csum”;
NativeQuery q=session.createNativeQuery(sql,RankingModel.class);
列表结果=q.List();

要告诉Hibernate使用自定义实体(数据bean)类,如
RankingModel.java
,您必须根据JPA规范用
@entity
注释每个此类类,并用
@Id
@column
注释每个可分配列(字段)。事实上,Hibernate尽最大努力尊重JPA2.0契约,并支持来自
javax.persistence
包的所有相关Java注释

执行此操作时,请确保每个实体类都有一个唯一的标识符字段,如中所述

以下是实体类的外观:

@Entity
public class RankingModel
{
    @Id
    public int id;

    @Column
    public int a;

    @Column
    public int b;

    @Column
    public int csum;
}
如果要在数据库中持久化实体,则还必须使用
@Table
对该类进行注释。这显式地告诉Hibernate实体持久化使用哪个数据库表。我相信,对于仅获取数据而言,注释是不必要的


最后,告诉Hibernate实际查找所有(带注释的)实体类。这可以通过从
hbm.xml
中引用它们来实现,或者,对于像我这样的Java纯粹主义者,可以通过列出要扫描的Java包作为
LocalSessionFactoryBean
构造函数的参数来实现,正如在中很好地解释的那样,您能发布您的
RankingModel.Java
吗?似乎该对象没有将
a
b
sum
作为实例变量。在javadoc中,在弃用警告之后,有这样一条注释:
@todo开发一种新的方法来实现结果转换器
。。。目前可能没有定义的迁移路径。最近的概念是
ResultSetMapping
,但我不确定它是否像resultsettransformers.Nope那样灵活。我已经和开发人员谈过了,这是一个有待解决的问题。如果我只想要一个带别名的HashMap,而不是实体类objectadding一个@Entity创建一个我不想要的物理表,该怎么办。
String sql = "select a, b, sum (c) csum from a group by a, b";
    NativeQuery<?> q = session.createNativeQuery (sql).addSynchronizedEntityClass( RankingModel.class );
    List<RankingModel> results = (List<RankingModel>)q.list ();
String sql = "SELECT a, b, sum(c) csum FROM a GROUP BY a, b";
NativeQuery<RankingModel> q = session.createNativeQuery(sql, RankingModel.class);
List<RankingModel> results = q.list();
@Entity
public class RankingModel
{
    @Id
    public int id;

    @Column
    public int a;

    @Column
    public int b;

    @Column
    public int csum;
}