Hibernate Native Query with 5.2.10

时间:2017-05-09 22:59:47

标签: java 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 ();

RankingModel的样子:

public class RankingModel
{
    public int a, b, csum;
}

但是,对于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 ();

但是,此代码失败了:

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)

任何人都知道我错过了什么?

3 个答案:

答案 0 :(得分:1)

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();

答案 1 :(得分:0)

您可以尝试使用

进行修复
<View style={{ height: 40, flexDirection: 'row' }} key={key}>

它会起作用,但在IDE中会发出警告。

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 ();

答案 2 :(得分:0)

要告诉Hibernate使用自定义实体(数据bean)类RankingModel.java,您必须使用@Entity注释每个此类,并使用@Id或每个可指定列(字段)注释@Columnjavax.persistence,根据JPA规范。事实上,Hibernate尽力尊重JPA 2.0合同,并支持@Entity public class RankingModel { @Id public int id; @Column public int a; @Column public int b; @Column public int csum; } 包中的所有相关Java注释。

在执行此操作时,请确保每个实体类都具有hibernate exception: org.hibernate.AnnotationException: No identifier specified for entity: com..domain.idea.MAE_MFEView

中提到的唯一标识符字段

以下是您的实体类应该是什么样的:

@Table

如果要将实体保留在数据库中,则该类也必须使用hbm.xml进行注释。这明确告诉Hibernate将哪个数据库表用于实体持久性。对于仅提取数据,我认为没有必要使用注释。

最后,告诉Hibernate实际查找所有(带注释的)实体类。这可以通过从LocalSessionFactoryBean引用它们来实现,或者对于像我这样的Java纯粹主义者来说,通过列出Java包作为for sublist in list: print sublist[1] 构造函数的参数进行扫描,正如在How to scan packages for Hibernate entities instead of using hbm.xml?中所解释的那样