20

我试图获取对在我的自定义实现 ( ) 中UserRepository扩展的存储库接口 () 的引用,以便访问 Spring JPA 提供的所有方法。CrudRepositoryUserRepositoryExtensionImpl

粗扩展:

@Repository
public interface UserRepository extends CrudRepository<User, String>, UserRepositoryExtension<RosterUser> {
    ...any custom spring JPA methods...
}

扩展接口:

@Repository
public interface UserRepositoryExtension <T> {
   public T put(T entity);
}

自定义实现:

public class UserRepositoryExtensionImpl implements UserRepositoryExtension<User> {

    UserRepository userRepository;

    @Autowired
    public UserRepositoryExtensionImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public User put(User user) {
        System.out.println(user + "was put");
        // ...put logic here
        return null;
    }...
}

但是,我无法注入,UserRepository因为存在循环依赖项(假设UserRepository扩展了 my 实现的接口UserRepositoryImpl)。我收到以下错误:

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name '    userRepositoryImpl': Requested bean is currently in creation: Is there an unresolvable circular     reference?

一个可能但不太理想的解决方案是注入和EntityManager进入UserRepositoryImp,但在这种情况下,我无权访问由 提供的任何 Spring JPA 方法CrudRepository,或我可能在 UserRepository 中创建的任何其他方法。

关于如何解决这个问题的任何建议?

任何帮助将不胜感激。

编辑:正如@shelley 的回答中提到的,我能够通过进行 3 处更改来解决这个问题:

  • 删除@RepositoryUserRepositoryExtensionImpl
  • 重命名UserRepositoryExtensionImplUserRepositoryImpl. 显然,这使 Spring 意识到实现的存在。参见Spring 文档
  • 删除我的构造函数并将 移动@Autowired到该userRepository字段

成功!

4

6 回答 6

12

为了使它起作用,需要更改一些小事情:

  • 从自定义存储库接口 ( ) 中删除@Repository注释。UserRepositoryExtension

  • 自定义存储库实现实际上应该命名为“ <StandardRepository>Impl”而不是“ <CustomRepository>Impl”。在您的代码示例中,这应该是UserRepositoryImpl而不是UserRepositoryExtensionImpl.

于 2013-02-28T17:00:42.183 回答
4

正如雪莱指出的那样,命名对于使自动接线工作非常重要。在下面的示例中,我为我的自定义接口及其实现遵循了正确的命名标准。但是我扩展 JpaRepository 的接口被命名为“ItemDao”而不是“ItemRepository”,这导致 spring 完全忽略了我的自定义实现......

OBS!!!应该是“ItemRepository”

@Repository
public interface ItemDao extends JpaRepository<Item, Long>, ItemRepositoryCustom {}

我的界面

interface ItemRepositoryCustom {...}

我的实现类

class ItemRepositoryImpl implements ItemRepositoryCustom {...}

如果有人有类似的问题,请按照以下链接中的 spring 文档中使用的命名标准开始。

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations

于 2013-05-21T07:31:25.703 回答
0

您应该遵循在 Spring Data JPA 中创建自定义存储库实现的定义明确的方法。基本上你需要扩展CrudRepository,所以你不必在你的自定义实现中注入它的实例。

于 2013-02-28T07:50:30.187 回答
0

我已经通过ApplicationContext使用applicationContext.getBean(UserRepository.class). 它以这种方式工作。

于 2013-02-28T21:29:20.590 回答
0

那么在这种情况下,我建议使用@Lazy注释。

public class MyCustomRepositoryImpl implements MyCustomRepository {

    @Lazy
    @Autowired
    private MyRepository myRepository;

    @Override
    public boolean customMethod() {
       return myRepository.count() > 0;
    }

}

使用构造函数参数 Spring 尝试创建需要您自定义存储库的“基本”存储库类,该存储库需要您“基本”存储库 - 具有循环依赖的典型情况。

没有@Lazy但只有@Autowired它也不会工作(基本回购的工厂bean会有问题)。

我认为在这种情况下,这@Lazy是最优雅的解决方案。

于 2018-12-17T14:34:10.880 回答
0

我发现我不需要@Autowire

public interface UserRepository extends 
    UserRepositoryBasic,
    UserRepositoryExtension 
{ 
}

public interface UserRepositoryBasic extends
    JpaRepository<User, String>
{
    // standard Spring Data methods, like findByLogin
}

public interface UserRepositoryExtension 
{
    public void customMethod();
}

public class UserRepositoryExtensionImpl implements
    UserRepositoryExtension 
{
    private final UserRepositoryBasic userRepositoryBasic;

    // constructor-based injection
    public UserRepositoryExtensionImpl(
        UserRepositoryBasic userRepositoryBasic)
    {
        this.userRepositoryBasic = userRepositoryBasic;
    }

    public void customMethod() 
    {
        // we can call all basic Spring Data methods using
        // userRepositoryBasic
    }
}
于 2018-07-30T22:43:59.310 回答