java - JPA Query with HQL and pageable create subselect with * return 并生成别名错误

标签 java mysql spring hibernate jpa

所以我想从 JPA 查询返回多个对象,该查询也允许分页,这样我就可以只返回它返回的前 10 个。

JPA: Query that returns multiple entities

问题是,如果我将 pageable 添加到方法定义中,那么它会将整个 select 语句捆绑在 select * from (original_query) where rownum <= size; 中。如果我删除可分页,它会在没有子选择的情况下执行 original_query 并且工作正常。但是每次我添加 pageable 并执行 select * 时,它都会抛出以下错误,因为我没有为 return 语句设置别名。

Exception in thread "main" org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:236) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:219) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491) at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy82.retrieveQualifyingOffers(Unknown Source) at com.comcast.qe.dataload.RunApp.main(RunApp.java:35) Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:79) at org.hibernate.loader.Loader.getResultSet(Loader.java:2123) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1911) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887) at org.hibernate.loader.Loader.doQuery(Loader.java:932) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) at org.hibernate.loader.Loader.doList(Loader.java:2615) at org.hibernate.loader.Loader.doList(Loader.java:2598) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430) at org.hibernate.loader.Loader.list(Loader.java:2425) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1473) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1426) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1398) at org.hibernate.Query.getResultList(Query.java:427) at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:119) at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:83) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:476) at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ... 8 more Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Every derived table must have its own alias at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:409) at com.mysql.jdbc.Util.getInstance(Util.java:384) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113) at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2275) at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) ... 38 more Blockquote

[更新] 我已经在 . sql 作为正确的选择语句出现,但随后使用 oracle 方言执行子查询。 它在类 org.hibernate.loader.Loader ( http://docs.jboss.org/hibernate/orm/4.1/javadocs/index.html?org/hibernate/loader/Loader.html )

作为 select blah_0.id, blah_0.peropty from table blah where property = value 但随后变成 select * from (select blah_0.id, blah_0.peropty from table blah where property = value) where rownum >= 10

    protected SqlStatementWrapper executeQueryStatement(
        String sqlStatement,
        QueryParameters queryParameters,
        boolean scroll,
        List<AfterLoadAction> afterLoadActions,
        SharedSessionContractImplementor session) throws SQLException {

    // Processing query filters.
    queryParameters.processFilters( sqlStatement, session );

    // Applying LIMIT clause.
    final LimitHandler limitHandler = getLimitHandler(
            queryParameters.getRowSelection()
    );
    String sql = limitHandler.processSql( queryParameters.getFilteredSQL(), queryParameters.getRowSelection() );

    // Adding locks and comments.
    sql = preprocessSQL( sql, queryParameters, getFactory().getDialect(), afterLoadActions );

    final PreparedStatement st = prepareQueryStatement( sql, queryParameters, limitHandler, scroll, session );
    return new SqlStatementWrapper(
            st, getResultSet(
            st,
            queryParameters.getRowSelection(),
            limitHandler,
            queryParameters.hasAutoDiscoverScalarTypes(),
            session
    )
    );
}

也许创造一种新的方言?我似乎无法处理 hibernate 供应商适配器,它只是转到 oracle。

最佳答案

我需要设置 MySQL5Dialect 来生成正确的查询。总是简单的配置。

    LocalContainerEntityManagerFactoryBean lcemfb = EntityManagerFactory(merlinDataSource(),
            new String[]{"packages.to.be.scaned"});
    Properties props = new Properties();
    props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
    props.setProperty("hibernate.show_sql", String.valueOf(showQueies));
    lcemfb.setJpaProperties(props);

关于java - JPA Query with HQL and pageable create subselect with * return 并生成别名错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43544978/

相关文章:

java - 难以理解 <? Java 中扩展 T> 通配符

java - 如何在不从中删除先前结果的情况下更新结果集

php - MySQL select 查询与 join 以及大量结果优化

java - 运行测试时排除 SpringApplicationRunListener

java - 媒体元数据检索器 JNI : getEmbeddedPicture failed

Eclipse 和 JDK 7

java - 从 Java 填充邮戳模板

java - 为 play 框架和 spring 定制 secureSocial(依赖注入(inject))

mysql - 如何将 iso-8601 时间戳转换为 MySQL DATETIME

php - fatal error : Uncaught Error: Call to undefined function mysql_close()