PROBLEM
Let’s assume we have the following Spring Data JPA repository…
public interface ProjectRepository extends JpaRepository<Project, Long>, ProjectRepositoryCustom {
Project findByName(String name);
}
… this repository has some custom implementation…
public interface ProjectRepositoryCustom {
Project doCustom(String name);
}
… this custom implementation depends on the original repository to reuse existing APIs…
public final class ProjectRepositoryImpl implements ProjectRepositoryCustom {
private final ProjectRepository projectRepository;
@Autowired
public ProjectRepositoryImpl(final ProjectRepository projectRepository) {
this.projectRepository = projectRepository;
}
@Override
public Project doCustom(final String name) {
final Project project = projectRepository.findByName(name);
return ...
}
}
When we run the code, we get the following exception:-
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'projectRepositoryImpl': Requested bean
is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:347)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
SOLUTION
To fix the circular reference problem, instead of auto-wiring ProjectRepository
using the constructor, auto-wire using the field or setter method:-
public final class ProjectRepositoryImpl implements ProjectRepositoryCustom {
// this field cannot be `final` anymore
private ProjectRepository projectRepository;
@Autowired
public void setProjectRepository(final ProjectRepository projectRepository) {
this.projectRepository = projectRepository;
}
@Override
public Project doCustom(final String name) {
final Project project = projectRepository.findByName(name);
return ...
}
}
Leave a Reply