JPQL带有LEFT JOIN查询的命名查询参数引发异常

时间:2019-05-30 05:34:54

标签: spring jpa jpql

我是spring数据的新手。我有一个使用JPQL的LEFT Join查询,并且在左表中使用了命名查询参数,但是却出现一个异常“该位置为[1]的参数不存在。

我有2个实体具有Many2One关系的Post和Comments。我想获取所有基于命名查询参数的Post以及与该Post相关的最新Comment。以下是实体和JPQL

@Entity
public class Post{
  @Id
  @GeneratedValue
  private long id;
  private String authorId;
}

@Entity
public class Comment {
  @Id
  @GeneratedValue
  private long id;
  private long creationTime;
  @ManyToOne
  @JoinColumn(name="post_id")
  private Post post;
}

I have scala code for my repository:

@Repository
trait PostRepository extends PagingAndSortingRepository[Post,Long] {

  @Query("SELECT P, COM FROM Post P "
    + "LEFT JOIN FETCH  Comment COM on COM.creationTime = "
    + "(SELECT MAX(COM2.creationTime) from Comment COM2 "
    + "WHERE P.id = COM2.post_id GROUP BY COM2.post_id) "
    + "WHERE P.authorId = :authorId"
  )
  def getPosts(@Param("authorId") authorId:String) : List[Array[Object]]
}

如果我不使用命名查询参数,那么就没有异常,但是一旦我添加了“ WHERE P.authorId =:authorId”,就会得到与命名参数相关的异常。我无法找出问题所在。

如果JPQL不是我要查询的方式,您能否建议/提供一个示例,说明如何使用spring数据(也许是Specification?)进行此操作。我对此并不陌生,因此非常感谢任何示例代码。

Caused by: java.lang.IllegalArgumentException: Parameter with that position [1] did not exist

            at org.hibernate.jpa.spi.BaseQueryImpl.findParameterRegistration(BaseQueryImpl.java:502) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]

            at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:692) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]

            at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:181) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]

            at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:32) ~[hibernate-entitymanager-5.0.12.Final.jar!/:5.0.12.Final]

            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]

            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]

            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]

            at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]

            at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:372) ~[spring-orm-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at com.sun.proxy.$Proxy204.setParameter(Unknown Source) ~[na:na]

            at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:141) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.bind(StringQueryParameterBinder.java:61) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:101) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.SpelExpressionStringQueryParameterBinder.bind(SpelExpressionStringQueryParameterBinder.java:76) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:161) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:152) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:81) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:123) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:87) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:116) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:106) ~[spring-data-jpa-1.11.10.RELEASE.jar!/:na]

            at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:492) ~[spring-data-commons-1.13.10.RELEASE.jar!/:na]

            at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:475) ~[spring-data-commons-1.13.10.RELEASE.jar!/:na]

            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) ~[spring-data-commons-1.13.10.RELEASE.jar!/:na]

            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) ~[spring-tx-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.14.RELEASE.jar!/:4.3.14.RELEASE]

            ... 152 common frames omitted

1 个答案:

答案 0 :(得分:0)

您可以将查询日志级别的休眠生成设置为FINEST,然后查看生成的SQL。我认为正在生成的sql中存在问题。
我在项目中运行了代码,输出查询如下:

select id, authorId, creationTime from post // creationTime comes from comment but is still generated as belonging to post

也许这可以帮助您Hibernate show real SQL

问题是您想检索2个对象实体作为对象中的响应,而好的方法是检索元组/ mapEntry或类似对象。

SELECT new java.util.AbstractMap.SimpleEntry(post, comment )