所以我想从JPA查询中做一个多对象返回,该查询也允许可分页,这样我只能返回它返回的前10个。
JPA: Query that returns multiple entities
问题在于,如果我将pageable添加到方法定义中,那么它将整个select语句捆绑在select * from(original_query)中,其中rownum< = size;。如果我删除pageable它会在没有subselect的情况下执行original_query并且工作正常。但每次我添加pageable并执行select *它会抛出以下错误,因为我没有别名的return语句。
线程中的异常" main" org.springframework.dao.InvalidDataAccessResourceUsageException:无法提取ResultSet; SQL [不适用];嵌套异常是org.hibernate.exception.SQLGrammarException:无法提取ResultSet 在org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:236) 在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) 在org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor $ CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy。$ Proxy82.retrieveQualifyingOffers(Unknown Source) 在com.comcast.qe.dataload.RunApp.main(RunApp.java:35) 引起:org.hibernate.exception.SQLGrammarException:无法提取ResultSet 在org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:63) 在org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) 在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) 在org.hibernate.loader.Loader.getResultSet(Loader.java:2123) 在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1911) 在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887) 在org.hibernate.loader.Loader.doQuery(Loader.java:932) 在org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) 在org.hibernate.loader.Loader.doList(Loader.java:2615) 在org.hibernate.loader.Loader.doList(Loader.java:2598) 在org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430) 在org.hibernate.loader.Loader.list(Loader.java:2425) 在org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502) 在org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) 在org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) 在org.hibernate.internal.SessionImpl.list(SessionImpl.java:1473) 在org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1426) 在org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1398) 在org.hibernate.Query.getResultList(Query.java:427) 在org.springframework.data.jpa.repository.query.JpaQueryExecution $ CollectionExecution.doExecute(JpaQueryExecution.java:119) 在org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:83) 在org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116) 在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) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 在org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) 在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) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ......还有8个 引起:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:每个派生表必须有自己的别名 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) 在com.mysql.jdbc.Util.handleNewInstance(Util.java:409) 在com.mysql.jdbc.Util.getInstance(Util.java:384) 在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054) 在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566) 在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498) 在com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959) 在com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113) 在com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568) 在com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113) 在com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2275) 在com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) 在com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70) ......还有38个 块引用
[UPDATE] 我找到了导致问题的代码。 sql作为右选择语句进入,但随后使用oracle方言执行子查询。 它在类org.hibernate.loader.Loader(http://docs.jboss.org/hibernate/orm/4.1/javadocs/index.html?org/hibernate/loader/Loader.html)
中进来了 从表格中选择blah_0.id,blah_0.peropty,其中property = value但是后来变成select * from(select blah_0.id,blah_0.peropty from table blah where property = value)其中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。
答案 0 :(得分:1)
我需要设置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);
答案 1 :(得分:0)
你可以让你的方法返回List<>
而不是Page<>
,就像我相信它会避免触发计数查询一样。
它只会限制查询只查找给定范围的实体