[英]CrudRepository inside my custom repository implementation
I am attempting to get a reference to my repository interface ( UserRepository
) that extends CrudRepository
within my custom implementation ( UserRepositoryExtensionImpl
) in order to gain access to all the methods provided by Spring JPA. 我试图获得对我的存储库接口(
UserRepository
)的引用,该接口在我的自定义实现( UserRepositoryExtensionImpl
)中扩展CrudRepository
,以便获得对Spring JPA提供的所有方法的访问。
Crud Extension: Crud扩展:
@Repository
public interface UserRepository extends CrudRepository<User, String>, UserRepositoryExtension<RosterUser> {
...any custom spring JPA methods...
}
Extension Interface: 扩展接口:
@Repository
public interface UserRepositoryExtension <T> {
public T put(T entity);
}
Custom Implementation: 定制实施:
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;
}...
}
However, I am unable to inject UserRepository
since a circular dependency exists (given that UserRepository
extends the interface implemented by my UserRepositoryImpl
). 但是,我无法注入
UserRepository
因为存在循环依赖(假设UserRepository
扩展了我的UserRepositoryImpl
实现的接口)。 I am getting the following error: 我收到以下错误:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ' userRepositoryImpl': Requested bean is currently in creation: Is there an unresolvable circular reference?
A possible, but less than ideal solution would be to inject and EntityManager
into UserRepositoryImp
, but in that case, I do not have access to any of the Spring JPA methods provided by CrudRepository
, or any additional methods that I might have created in UserRepository. 一个可能但不太理想的解决方案是将
EntityManager
注入UserRepositoryImp
,但在这种情况下,我无法访问CrudRepository
提供的任何Spring JPA方法,或者我可能在UserRepository中创建的任何其他方法。
Any suggestions on how to get around this? 有关如何绕过这个的任何建议?
Any help would be greatly appreciated. 任何帮助将不胜感激。
EDIT: As mentioned in @shelley's answer, I was able to solve this by making 3 changes: 编辑:正如在@ Shelley的回答中提到的,我能够通过进行3次更改来解决这个问题:
@Repository
from UserRepositoryExtensionImpl
@Repository
从UserRepositoryExtensionImpl
UserRepositoryExtensionImpl
to UserRepositoryImpl
. UserRepositoryExtensionImpl
重命名为UserRepositoryImpl
。 Apparently this makes Spring aware of the implementation's existence. @Autowired
to the userRepository
field @Autowired
移动到userRepository
字段 SUCCESS! 成功!
A couple small things need to be changed in order for this to work: 为了实现这一点,需要更改几件小事:
Remove the @Repository
annotation from the custom repository interface ( UserRepositoryExtension
). 取下
@Repository
从定制库接口(注释UserRepositoryExtension
)。
The custom repository implementation should actually be named " <StandardRepository>Impl
" rather than " <CustomRepository>Impl
". 自定义存储库实现实际上应该命名为“
<StandardRepository>Impl
”而不是“ <CustomRepository>Impl
”。 In your code example, this should be UserRepositoryImpl
instead of UserRepositoryExtensionImpl
. 在您的代码示例中,这应该是
UserRepositoryImpl
而不是UserRepositoryExtensionImpl
。
As shelley pointed out, the naming is really important to make the autowire work. 正如Shelley指出的那样,命名对于使autowire工作非常重要。 In the example below, I follow the right naming standard for my custom interface and its implementation.
在下面的示例中,我遵循自定义界面及其实现的正确命名标准。 But my interface that extended the JpaRepository was named “ItemDao” instead of “ItemRepository”, this resulted in that spring ignored my custom implementation altogether...
但我扩展JpaRepository的界面被命名为“ItemDao”而不是“ItemRepository”,这导致Spring完全忽略了我的自定义实现......
OBS!!! OBS! Should be "ItemRepository"
应该是“ItemRepository”
@Repository
public interface ItemDao extends JpaRepository<Item, Long>, ItemRepositoryCustom {}
my interface 我的界面
interface ItemRepositoryCustom {...}
my implementation class 我的实现类
class ItemRepositoryImpl implements ItemRepositoryCustom {...}
If anyone have similar problems, start by following the naming standard that is used in the spring documentation at the link below. 如果有人遇到类似问题,请首先遵循以下链接中弹簧文档中使用的命名标准。
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations
There is a well defined way to create custom repository implementations in Spring Data JPA which you should follow. 有一种定义明确的方法可以在Spring Data JPA中创建自定义存储库实现 ,您应该遵循这些方法。 Basically you need to extend
CrudRepository
so you don't have to inject an instance of it in your custom implementation. 基本上你需要扩展
CrudRepository
这样你就不必在自定义实现中注入它的实例。
I have solved problem by injecting ApplicationContext
and getting bean in lazy way using applicationContext.getBean(UserRepository.class)
. 我通过使用
applicationContext.getBean(UserRepository.class)
注入ApplicationContext
并以懒惰的方式获取bean来解决问题。 It works this way. 它以这种方式工作。
I found I way of how to do it without the need for @Autowire
: 我找到了如何在不需要
@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
}
}
Well in this case I suggest to use the @Lazy
annotation. 那么在这种情况下我建议使用
@Lazy
注释。
public class MyCustomRepositoryImpl implements MyCustomRepository {
@Lazy
@Autowired
private MyRepository myRepository;
@Override
public boolean customMethod() {
return myRepository.count() > 0;
}
}
With constructor parameter Spring tries to create the "basic" repository class which require you custom repository which requires you "basic" repository - the typical case with circular dependency. 使用构造函数参数Spring尝试创建“基本”存储库类,它需要您自定义存储库,这需要您“基本”存储库 - 典型的循环依赖情况。
Without @Lazy
but with only the @Autowired
it also won't work (there will be problem with factory bean for the basic repo). 没有
@Lazy
但只有@Autowired
它也不会工作(基本@Lazy
工厂bean会有问题)。
I think in this case the @Lazy
is the most elegant solution. 我想在这种情况下
@Lazy
是最优雅的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.