【问题标题】:Spring Data JPA Repository Interface ImplementaionSpring Data JPA 存储库接口实现
【发布时间】:2015-02-13 05:18:57
【问题描述】:

我的存储库定义如下:

 public interface MyRepository extends JpaRepository<MyClass, Long> {
      List<Long> findAllItemsForUser(String user);
 }

我也有一个实现,因为我想使用原生 SQL 查询:

public class MyRepositoryImpl extends SimpleJpaRepository<MyClass, Long> implements MyRepository {

 @PersistenceContext
 EntityManager entityManager;

  @Autowired
  private MyRepository repository;

  ...
  public List<Long> findAllItemsForUser(String user)
  {
      String sql = "select m.id from ..."; //Complex SQL Query here with several joins;
      List<Long> list = (List<Long>)entityManager.createNativeQuery(sql).setParameter(1,user).getResultList();

      return list;
  }
  ...
  }

现在,我想使用 Spring Data JPA 的标准 findByIdIn 子句来使用这个 id 输出列表。我尝试在我的界面中添加一个方法。然后它要求我执行相同的操作。

我按如下方式实现它,但它在下面的实现中引发了一个异常,该异常源自 repository.findByIdIn():

@Override
public List<MyClass> findByIdIn(List<Long> idList) {
    // TODO Auto-generated method stub
    return repository.findByIdIn(idList);
}

at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) ~[spring-tx-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) ~[spring-tx-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) ~[spring-tx-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]
at $Proxy140.findByIdIn(Unknown Source) ~[na:na]
at sun.reflect.GeneratedMethodAccessor283.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_05]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_05]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:405) ~[spring-data-commons-1.8.4.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:380) ~[spring-data-commons-1.8.4.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:344) ~[spring-data-commons-1.8.4.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.7.RELEASE.jar:4.0.7.RELEASE]

【问题讨论】:

  • 堆栈跟踪中缺少一些行。你能添加这些行吗?

标签: spring jpa repository spring-data


【解决方案1】:

最后我得到的是一组单独的接口——一个带有纯 JPA 接口,一个带有自定义 JDBC 实现。当存在实现时,Spring 似乎无法派生基于方法名称的查询。

因此,使用单独的接口似乎是唯一的出路。

【讨论】:

    【解决方案2】:

    将接口MyRepository 的实例注入MyRepositoryImpl,然后使用该注入的实例调用findByIdIn

    (你不能在MyRepositoryImpl中实现findByIdIn

    public class MyRepositoryImpl extends SimpleJpaRepository<MyClass, Long>
                               implements MyRepository {
    
      @PersistenceContext
      EntityManager entityManager;
    
      @Autowired
      private MyRepository repository;
    
      ...
      public List<Long> findAllItemsForUser(String user) {
          ...
          return repository.findByIdIn(...)    // <----
      }
      ...
    }
    

    【讨论】:

    • 我将 findByIdIn 方法添加到我的界面,我的 Impl 在 IDE 中抛出此错误:MyRepositoryImpl 类型必须实现继承的抽象方法 MyRepository.findByIdIn(List)
    猜你喜欢
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2018-10-06
    • 2018-06-15
    相关资源
    最近更新 更多