我的自定义存储库实现中的CrudRepository

时间:2013-02-27 23:56:07

标签: java spring hibernate spring-mvc spring-data-jpa

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

Crud Extension:

@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扩展了我的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,但在这种情况下,我无法访问{{1}提供的任何Spring JPA方法我可能在UserRepository中创建的任何其他方法。

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

非常感谢任何帮助。

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

  • CrudRepository
  • 中删除@Repository
  • UserRepositoryExtensionImpl重命名为UserRepositoryExtensionImpl。显然,这使得Spring意识到实现的存在。请参阅Spring Doc
  • 删除我的构造函数并将UserRepositoryImpl移至@Autowired字段

SUCCESS!

6 个答案:

答案 0 :(得分:11)

为了实现这一点,需要更改几件小事:

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

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

答案 1 :(得分:4)

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

OBS !!!应该是“ItemRepository”

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

我的界面

interface ItemRepositoryCustom {...}

我的实施课

class ItemRepositoryImpl implements ItemRepositoryCustom {...}

如果有人遇到类似问题,请首先遵循以下链接中弹簧文档中使用的命名标准。

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

答案 2 :(得分:0)

您应该遵循well defined way to create custom repository implementations in Spring Data JPA。基本上你需要扩展CrudRepository,这样你就不必在自定义实现中注入它的实例。

答案 3 :(得分:0)

我通过使用ApplicationContext注入applicationContext.getBean(UserRepository.class)并以懒惰的方式获取bean来解决问题。 它以这种方式工作。

答案 4 :(得分: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
    }
}

答案 5 :(得分:0)

在这种情况下,我建议使用const input = Object.create(null); input.foo = 'bar'; console.log(input);批注。

@Lazy

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

如果没有public class MyCustomRepositoryImpl implements MyCustomRepository { @Lazy @Autowired private MyRepository myRepository; @Override public boolean customMethod() { return myRepository.count() > 0; } } ,但只有@Lazy,它也将不起作用(基本存储库的工厂bean会出现问题)。

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