修改本机查询不能有命名参数绑定?

我在JpaRepository中指定了以下修改本机查询。

public interface PlayerStatisticsRepository extends JpaRepository { @Modifying @Query(value = "INSERT INTO playerstatistics(enteredTheFieldAtInSeconds, leftTheFieldAtInSeconds, hometeam_name, matchday_matchdaynumber, playedFromTheFirstWhistleblow, player_id) VALUES (:enteredTheFieldAtInSeconds, :leftTheFieldAtInSeconds, :#{#match.primaryKey.homeTeam.name}, :#{#match.primaryKey.matchday.matchdayNumber}, :playedFromTheFirstWhistleblow, :#{#player.id})", nativeQuery = true) void insertIntoPlayerStatistics(int enteredTheFieldAtInSeconds, int leftTheFieldAtInSeconds, boolean playedFromTheFirstWhistleblow, Match match, Player player); } 

不幸的是,它以运行时的exception结束,说可能是match参数的绑定不存在,而它显然是。

 org.springframework.dao.InvalidDataAccessApiUsageException: No parameter binding found for name match!; nested exception is java.lang.IllegalArgumentException: No parameter binding found for name match! at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) 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.$Proxy185.insertIntoPlayerStatistics(Unknown Source) at web_xtra_klasa.SuspensionFromThePreviousRoundTest.ifPlayerHas2YellowCardsFromThePreviousRoundAndReceivedAnotherTwoThenShouldBeSuspendedOnTheNextMatchday(SuspensionFromThePreviousRoundTest.java:425) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.IllegalArgumentException: No parameter binding found for name match! at org.springframework.data.jpa.repository.query.StringQuery.getBindingFor(StringQuery.java:118) at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.getBindingFor(StringQueryParameterBinder.java:75) at org.springframework.data.jpa.repository.query.StringQueryParameterBinder.bind(StringQueryParameterBinder.java:60) at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:100) at org.springframework.data.jpa.repository.query.SpelExpressionStringQueryParameterBinder.bind(SpelExpressionStringQueryParameterBinder.java:69) at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:160) at org.springframework.data.jpa.repository.query.ParameterBinder.bindAndPrepare(ParameterBinder.java:151) at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateQuery(AbstractStringBasedJpaQuery.java:81) at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:190) at org.springframework.data.jpa.repository.query.JpaQueryExecution$ModifyingExecution.doExecute(JpaQueryExecution.java:242) at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:82) 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: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: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) ... 38 more 

在这里的一条评论中,有人写道,如果有多个参数,SpEL不起作用,但我还有另一个非本机的选择查询,它确实有多个参数并且运行完美。

索引访问就像一个魅力。

 @Modifying @Query(value = "INSERT INTO playerstatistics(enteredTheFieldAtInSeconds, leftTheFieldAtInSeconds, hometeam_name, matchday_matchdaynumber, playedFromTheFirstWhistleblow, player_id) VALUES (?#{[0]}, ?#{[1]}, ?#{[3].primaryKey.homeTeam.name}, ?#{[3].primaryKey.matchday.matchdayNumber}, ?#{[2]}, ?#{[4].id})", nativeQuery = true) void insertIntoPlayerStatistics(int enteredTheFieldAtInSeconds, int leftTheFieldAtInSeconds, boolean playedFromTheFirstWhistleblow, Match match, Player player); 

有没有人遇到过类似的问题? 这是一个错误吗? 我找不到任何未解决的问题。

对于这个特殊的派对,我可能会有点迟到,但遇到了同样的问题。 事实certificate,你不应该混合传递参数的方式 – 如果你使用SpEL,要保持一致并在任何地方使用它。 例如

INSERT INTO x(x,y,z)VALUES(:x,:#{#y},?[0])

不行,但是

插入x(x,y,z)值(:#{#x},:#{#y},:#{#[4]})

运行得很好。

编辑:您显然注意到,您的第二个示例也可以,因为您始终在那里使用SpEL。

您需要完全按照本机查询中显示的顺序对参数进行排序,以便查询变为:

 @Query(value = "INSERT INTO playerstatistics(enteredTheFieldAtInSeconds, leftTheFieldAtInSeconds, hometeam_name, matchday_matchdaynumber, playedFromTheFirstWhistleblow, player_id) VALUES (:enteredTheFieldAtInSeconds, :leftTheFieldAtInSeconds, :#{#match.primaryKey.homeTeam.name}, :#{#match.primaryKey.matchday.matchdayNumber}, :playedFromTheFirstWhistleblow, :#{#player.id})", nativeQuery = true) void insertIntoPlayerStatistics(int enteredTheFieldAtInSeconds, int leftTheFieldAtInSeconds, Match match, boolean playedFromTheFirstWhistleblow, Player player);