繁体   English   中英

Spring Boot + Groovy + Spring JPA如何从排序查询中检索第一个?

[英]Spring Boot + Groovy + Spring JPA how to retrieve first one from sorted query?

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

@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
}

存储库类如下所示:

@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(选择第一个 ...)

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

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

MyEntity findTop1ByIdKeyField1OrderByIdAscLastUpdatedDesc(String keyValue)

此处参考: http : //docs.spring.io/spring-data/jpa/docs/current/reference/html/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM