【问题标题】:Spring Boot + Groovy + Spring JPA how to retrieve first one from sorted query?Spring Boot + Groovy + Spring JPA 如何从排序查询中检索第一个?
【发布时间】:2016-08-07 19:42:32
【问题描述】:

我有一个连接到 Informix 数据库的 Spring Boot + Spring JPA + Groovy 项目。 我正在为我的数据检索操作扩展存储库接口,我遇到了这样一种情况,即我有一个具有复合键的实体和一个需要检索排序(排序依据)查询的第一个查询的实体。 为了更好地理解这里是我的实体:

@Entity
@Table(name = 'table1')
class MyEntity {
   @EmbeddedId
   MyEntityId id

   // several more fields
}

@Embeddable
class MyEntityId implements Serialiable {
   @Column(name = 'keyField1')
   String keyField1

   @Column(name = 'lastUpdated')
   LocalDateTime lastUpdated
}

Repository 类如下所示:

@NoRepositoryBean
interface BaseDao<T, ID extends Serializable> extends Repository<T, ID>{
   // Default methods here
}

interface MyEntityDao extends BaseDao<MyEntity, MyEntityId> {
   MyEntity findFirstByIdKeyField1OrderByIdLastUpdated(String keyValue)
}

此处定义的查询不起作用,它返回有关“rownum”列未找到的错误。 但是,如果我在方法名称中只保留“First”或“OrderBy”,它会按预期工作,这意味着:这适用于“findIdKeyField1OrderByIdLastUpdated”,这也适用于“findFirstByIdKeyField1”,但不是 FirstBy + OrderBy 的组合。

关于我在这里缺少什么的任何想法/建议?

非常感谢:)

更新 这是我得到的堆栈跟踪:

org.springframework.orm.jpa.JpaSystemException: could not prepare statement; nested exception is org.hibernate.exception.GenericJDBCException: could not prepare statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:333)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
    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)
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:182)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1929)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1898)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1876)
    at org.hibernate.loader.Loader.doQuery(Loader.java:919)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
    at org.hibernate.loader.Loader.doList(Loader.java:2617)
    at org.hibernate.loader.Loader.doList(Loader.java:2600)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2429)
    at org.hibernate.loader.Loader.list(Loader.java:2424)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)
    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:1326)
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606)
    at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:529)
    at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:54)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:206)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:102)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:92)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482)
    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:280)
    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)
    ... 7 more
Caused by: java.sql.SQLException: Column (rownum) not found in any table in the query (or SLV is undefined).
    at com.informix.jdbc.IfxSqli.a(IfxSqli.java:3453)
    at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3770)
    at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2576)
    at com.informix.jdbc.IfxSqli.receiveMessage(IfxSqli.java:2492)
    at com.informix.jdbc.IfxSqli.executePrepare(IfxSqli.java:1360)
    at com.informix.jdbc.IfxPreparedStatement.e(IfxPreparedStatement.java:320)
    at com.informix.jdbc.IfxPreparedStatement.a(IfxPreparedStatement.java:300)
    at com.informix.jdbc.IfxPreparedStatement.<init>(IfxPreparedStatement.java:170)
    at com.informix.jdbc.IfxSqliConnect.h(IfxSqliConnect.java:6523)
    at com.informix.jdbc.IfxSqliConnect.prepareStatement(IfxSqliConnect.java:2334)
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108)
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:146)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172)
    ... 39 more
Caused by: java.sql.SQLException
    at com.informix.util.IfxErrMsg.getSQLException(IfxErrMsg.java:407)
    at com.informix.jdbc.IfxSqli.E(IfxSqli.java:3775)
    ... 52 more

正如我们所见,它试图检索一个名为“rownum”的列,该列不存在。生成的 SQL 如下所示:

Hibernate: 
    select
        * 
    from
        ( select
            table10_.lastUpdated as lastUpdated1_0_,
            table10_.keyField1 as keyField12_0_,
            .....
        from
           table1 table10_ 
        where
            table10_.keyField1=? 
        order by
            table10_.lastUpdated asc ) 
    where
        rownum <= ?

已解决!!!

我不小心在 application.yml 文件中将休眠方言声明为“Oracle”而不是“Informix”:-/ 这解决了问题,并且 SQL 按预期生成(选择 first 1 ...)

spring:
   jpa:
      properties:
         hibernate:
            dialect: org.hibernate.dialect.InformixDialect
            ...

【问题讨论】:

  • 当您询问异常时,总是发布异常的完整堆栈跟踪。

标签: java groovy spring-boot spring-data-jpa


【解决方案1】:

尝试向存储库方法添加 findTop1 前缀,如下所示:

MyEntity findTop1ByIdKeyField1OrderByIdAscLastUpdatedDesc(String keyValue)

参考这里:http://docs.spring.io/spring-data/jpa/docs/current/reference/html/

【讨论】:

  • findTop1By 给出与上面相同的结果(堆栈跟踪和生成的 SQL):(
猜你喜欢
  • 2021-10-13
  • 2021-03-03
  • 2021-09-15
  • 2022-01-24
  • 1970-01-01
  • 2019-07-18
  • 2018-08-06
  • 2017-10-10
  • 1970-01-01
相关资源
最近更新 更多