我正在尝试获取对我的自定义实现(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!
答案 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 {...}
如果有人遇到类似问题,请首先遵循以下链接中弹簧文档中使用的命名标准。
答案 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
是最优雅的解决方案。