【问题标题】:Hibernate Native Query with 5.2.10使用 5.2.10 休眠本机查询
【发布时间】:2017-10-08 10:21:14
【问题描述】:

在 Hibernate

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)

有人知道我错过了什么吗?

【问题讨论】:

  • 你能发布你的RankingModel.java吗?该对象似乎没有 absum 作为实例变量。
  • 在 javadoc 中,在弃用警告之后,有这样的评论:@todo develop a new approach to result transformers... 目前可能没有定义迁移路径。这个最接近的概念是ResultSetMapping,但我不确定它是否像结果集转换器一样灵活。

标签: java hibernate


【解决方案1】:

您可以尝试使用修复

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

它会工作,但在 IDE 中它会抛出警告。

或者

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

【讨论】:

  • 不。我已经和开发人员谈过了,这是一个 TODO。
【解决方案2】:
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();

【讨论】:

  • 如果我只想要一个带有别名而不是实体类对象的 HashMap 怎么办
【解决方案3】:

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

这样做时,请确保每个实体类都有一个唯一标识符字段,如 hibernate exception: org.hibernate.AnnotationException: No identifier specified for entity: com..domain.idea.MAE_MFEView 中所述

你的实体类应该是这样的:

@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 构造函数的参数,正如 How to scan packages for Hibernate entities instead of using hbm.xml? 中很好解释的那样

【讨论】:

  • 添加一个@Entity 会创建一个我不想要的物理表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 2016-06-14
相关资源
最近更新 更多