I'm working on a Spring Boot v1.4.2.RELEASE application with JPA.
I defined repository interfaces and implementations
ARepository
@Repository
public interface ARepository extends CrudRepository<A, String>, ARepositoryCustom, JpaSpecificationExecutor<A> {
}
ARepositoryCustom
@Repository
public interface ARepositoryCustom {
Page<A> findA(findAForm form, Pageable pageable);
}
ARepositoryImpl
@Repository
public class ARepositoryImpl implements ARepositoryCustom {
@Autowired
private ARepository aRepository;
@Override
public Page<A> findA(findAForm form, Pageable pageable) {
return aRepository.findAll(
where(ASpecs.codeLike(form.getCode()))
.and(ASpecs.labelLike(form.getLabel()))
.and(ASpecs.isActive()),
pageable);
}
}
And a service AServiceImpl
@Service
public class AServiceImpl implements AService {
private ARepository aRepository;
public AServiceImpl(ARepository aRepository) {
super();
this.aRepository = aRepository;
}
...
}
My application won't start with the message :
*************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: | aRepositoryImpl └─────┘
I followed all steps discribed in http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behaviour
Please help !
Laurent
What Is a Circular Dependency? A circular dependency occurs when a bean A depends on another bean B, and the bean B depends on bean A as well: Bean A → Bean B → Bean A. Of course, we could have more beans implied: Bean A → Bean B → Bean C → Bean D → Bean E → Bean A.
A cyclic dependency is an indication of a design or modeling problem in your software. Although you can construct your object graph by using property injection, you will ignore the root cause and add another problem: property injection causes Temporal Coupling. Instead, the solution is to look at the design closely.
Maven does not allow cyclic dependencies between projects, because otherwise it is not clear which project to build first. So you need to get rid of this cycle. One solution is the one you already mentioned, to create another project.
Use @Lazy
A simple way to break the cycle is by asking Spring to initialize one of the beans lazily. That is: instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it’s first needed.
@Service
public class AServiceImpl implements AService {
private final ARepository aRepository;
public AServiceImpl(@Lazy ARepository aRepository) {
super();
this.aRepository = aRepository;
}
...
}
source: https://www.baeldung.com/circular-dependencies-in-spring
There's a simple fix for your original problem: Just remove @Repository from ARepositoryCustom and from ARepositoryImpl. Keep all the naming and interface/class hierarchies. They are all OK.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With