有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate原生查询与5.2.10

在冬眠状态下<;在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) 个答案

  1. # 1 楼答案

    为了告诉Hibernate使用像RankingModel.java这样的自定义实体(数据bean)类,必须根据JPA规范,用@Entity注释每个这样的类,用@Id@Column注释每个可赋值列(字段)。事实上,Hibernate尽最大努力尊重JPA2.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?中很好地解释的那样

  2. # 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();
    
  3. # 3 楼答案

    你可以尝试使用

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