Post

Solving Circular Dependencies: @Lazy Is Just a Workaround

Solving Circular Dependencies: @Lazy Is Just a Workaround

Problem

While building the Gift API at Kakao Tech Campus, I ran into a circular dependency.

1
2
ProductService → OptionService
OptionService → ProductService

When creating an option, I needed to check if the product exists—so OptionService referenced ProductService. But ProductService also referenced OptionService for option-related logic.

When I started the app, a circular reference error popped up.


Temporary Fix: @Lazy

I slapped on the @Lazy annotation to get it working.

1
2
3
4
public OptionService(OptionRepository optionRepository, @Lazy ProductService productService) {
    this.optionRepository = optionRepository;
    this.productService = productService;
}

@Lazy delays bean creation until it’s actually used, dodging the circular reference error.


Mentor Feedback

But then my mentor gave me this:

“A circular reference is a sign that two classes are too tightly coupled. @Lazy can hide the error temporarily, but you should fix the design.”


Fundamental Solution

Methods my mentor suggested:

1. Check if they really need to depend on each other

  • Looking at the logic again, some of it didn’t need to go through a service
  • Some parts could be resolved by injecting the Repository directly

2. Make it unidirectional

  • See if bidirectional dependency can become unidirectional
  • Rearrange logic so one service doesn’t need the other

3. Introduce a Facade service

  • Create a higher-level service that coordinates both
  • Something like ProductOptionFacade that combines the two

unnamed 8.png


Lessons Learned

  • @Lazy hides the problem—it doesn’t solve it
  • Circular dependencies are a design smell
  • Direction of dependencies matters a lot in OOP
  • Fixing structure now saves headaches later

From Kakao Tech Campus 3rd cohort Gift API clone coding, summarizing mentor feedback.

This post is licensed under CC BY 4.0 by the author.