【问题标题】:Why are Spring Data repository method parameters names not available even on Java 8?为什么即使在 Java 8 上也没有 Spring Data 存储库方法参数名称?
【发布时间】:2017-03-24 10:35:25
【问题描述】:

我很难让测试通过 Pivotal 的 spring-boot 1.4 版本 from their examples 的示例项目,该项目显示 spring-data-jpa 在其 JPQL 中使用 未注释 命名参数 p>

例如

来自example.springdata.jpa.simple.SimpleUserRepository

 @Query("select u from User u where u.firstname = :firstname")
 List<User> findByFirstname(String firstname);

NB它没有使用@Param注解

这不在我的机器上运行。我在这里得到了详细的异常,从标题中可以不言自明。

Name for parameter binding must not be null or empty! For named parameters you need to use @Param for query method parameters on Java versions

所以我必须这样做:

@Query("select u from User u where u.firstname = ?1")
List<User> findByFirstname(String firstname);

或者这个:

@Query("select u from User u where u.firstname = :firstname")
List<User> findByFirstname(@Param("firstname") String firstname);

我正在使用什么:

  • 操作系统-Win7
  • Java - 1.8.0_112
  • IDE - Intellij IDEA 2016.2
  • JPA 版本-JPA v2.0
  • 配置-spring-boot-1.4.1

那么我设置示例的方式有问题吗?

spring-data-jpa 是否曾经包含一些很酷的功能来自动检测后来由于某种原因被删除的参数名称?

org.springframework.dao.InvalidDataAccessApiUsageException: Name for parameter binding must not be null or empty! For named parameters you need to use @Param for query method parameters on Java versions < 8.; nested exception is java.lang.IllegalArgumentException: Name for parameter binding must not be null or empty! For named parameters you need to use @Param for query method parameters on Java versions < 8.

    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.$Proxy75.findByFirstnameOrLastname(Unknown Source)

    at example.springdata.jpa.simple.SimpleUserRepositoryTests.findByFirstnameOrLastname(SimpleUserRepositoryTests.java:86)
      ====================================================================================================================
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    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.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

【问题讨论】:

  • 确保您使用的是 Java8... 否则它将无法正常工作。
  • 当然是。更新 Q。
  • 接下来你需要使用调试信息进行编译,否则它也不起作用。
  • 它正在使用调试信息进行编译。只是为了确保我在 Maven 中通过干净的重新编译和maven-compiler-plugin&lt;debug&gt;true&lt;/debug&gt;&lt;debuglevel&gt;lines,vars,source&lt;/debuglevel&gt; 运行它,而不是依赖 Intellij。
  • 是Java12还是Java8还是必须的?

标签: java spring annotations spring-data spring-data-jpa


【解决方案1】:

默认情况下,接口不保留参数名称信息——在任何 Java 版本中,即使没有设置 debug 标志。然而,Java 8 添加了一项功能,可以通过需要显式设置的新 -parameters 编译器标志来保留所有类型的参数信息。

在 Spring Data 示例存储库中查看 an example

【讨论】:

  • 有趣的是,这是我第一次需要在 CI 服务器上设置编译器标志。
  • 为什么不为一般构建启用它们?
  • @OliverDrotbohm 知道什么是gradle 等价物吗?链接的示例基于 maven。
猜你喜欢
  • 2019-03-25
  • 2016-10-11
  • 2017-03-16
  • 2021-11-11
  • 2015-03-20
  • 2011-04-14
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多