Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject Repository into Custom Repository instance cause circular reference #3320

Closed
devholic22 opened this issue Jan 18, 2024 · 2 comments
Closed
Labels
for: stackoverflow A question that's better suited to stackoverflow.com

Comments

@devholic22
Copy link
Contributor

First, I checked about two issue: #2384 , and this.

but I solve this problem by another way, I don't know why this way solved problem.

could I know Spring data JPA internal principle?

this is my example code.

  • <package 'domain'>
    • Board.java
    • BoardRepository.java
  • <package 'infrastructure'>
    • BoardJpaRepository.java
    • BoardJpaRepositoryImpl.java

With:

public interface BoardRepository {

    Long save(final Board board);
    ...
}
public interface BoardJpaRepository extends JpaRepository<Board, Long> {
}
@Repository
@RequiredArgsConstructor
public class BoardJpaRepositoryImpl implements BoardRepository {

    private final BoardJpaRepository boardJpaRepository;

    @Override
    public Long save(final Board board) {
        boardJpaRepository.save(board);
        ...
    }
}

Error:

┌─────┐
|  boardJpaRepositoryImpl defined in file [..../board/infrastructure/BoardJpaRepositoryImpl.class]
└─────┘

My Solution:
Instead use boardJpaRepositoryImpl, use boardRepositoryImpl (or jpaBoardRepositoryImpl). it worked to solve problem.

(I wanted to create repository implementations, both with and without using JPA. That's why I didn't use the name BoardRepositoryImpl. Instead, I intended to use BoardJpaRepositoryImpl to signify an implementation using JPA. I'm curious if there are any rules against using the combination of a Spring Data JPA interface and its corresponding impl class in situations like this.)

additionally, I tried to search spring data jpa documentation, and I knew about repositoryImplementationPostfix. Is there any connection with this?

thanks to check this issue, and I apologize if this problem too much similar previous issues.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 18, 2024
@mp911de
Copy link
Member

mp911de commented Jan 18, 2024

You cannot inject a repository facade into its own repository fragment as this creates a circular dependency. You could make the repository @Lazy or inject an ObjectProvider< BoardJpaRepository> to defer object resolution to a time after the objects are constructed.

@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale Jan 18, 2024
@mp911de mp911de added for: stackoverflow A question that's better suited to stackoverflow.com and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 18, 2024
@devholic22
Copy link
Contributor Author

devholic22 commented Jan 18, 2024

You cannot inject a repository facade into its own repository fragment as this creates a circular dependency. You could make the repository @Lazy or inject an ObjectProvider< BoardJpaRepository> to defer object resolution to a time after the objects are constructed.

As I know, In Spring, using @Lazy is discouraged due to the fact that it injects dependencies at the point when the bean is needed, not during the application loading phase. This can potentially lead to increased heap memory usage, especially when handling specific HTTP requests. (https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.spring-application.lazy-initialization)

In summary your answer, if the Spring Data JPA interface is named BoardRepository, creating an Impl instance containing this name (ex: BoardRepositoryImpl) may result in a circular reference issue?


@mp911de Upon referring to the official Spring Data JPA documentation, it is confirmed that a UserRepository, inheriting from CrudRepository, can have a custom implementation named UserRepositoryImpl. However, there doesn't seem to be information about @Lazy or circular reference in the documentation.

If it is not inconvenient, could you provide additional explanation or example?


I realized myself. In official documents, did not use the Spring Data JPA interface to process CRUD where used it as an implementation, but instead used the EntityManager.

In my situation, on the other hand, I referred to the Spring Data JPA interface where I used it as an implementation of Spring Data JPA.

I realized that the basic strategy of the Spring Data JPA implementation would eventually lead to a self-reference, which would result in a reference to my own interface.

I was able to find out by myself, but I'm sorry for the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: stackoverflow A question that's better suited to stackoverflow.com
Projects
None yet
Development

No branches or pull requests

3 participants