0

I have an entity class called Screenshot and and a repository declared as this:

public interface ScreenshotRepository extends JpaRepository<Screenshot, UUID>, ScreenshotRepositoryCustom

The custom repository is defined like this:

interface ScreenshotRepositoryCustom

and

class ScreenshotRepositoryImpl implements ScreenshotRepositoryCustom {
    private final ScreenshotRepository screenshotRepo;

    @Autowired
    public ScreenshotRepositoryImpl(ScreenshotRepository screenshotRepo) {
        this.screenshotRepo = screenshotRepo;
    }

This is following what's described in this other Stack Overflow question: How to add custom method to Spring Data JPA

Now, IntelliJ is giving me a warning:

Autowired members must be defined in a valid Spring bean

I tried adding these annotations to ScreenshotRepositoryImpl but none of the worked:

  • @Repository
  • @Component
  • @Service

but none work. Obviously some are wrong but I was experimenting. What's the correct annotation.

With @Repository, I get this error:

2017-11-23 12:30:04.064  WARN 20576 --- [  restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'screenshotsController' defined in file [C:\Users\pupeno\Documents\Dashman\java\dashmanserver\out\production\classes\tech\dashman\server\controllers\ScreenshotsController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'screenshotRepositoryImpl' defined in file [C:\Users\pupeno\Documents\Dashman\java\dashmanserver\out\production\classes\tech\dashman\server\models\ScreenshotRepositoryImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'screenshotRepositoryImpl': Requested bean is currently in creation: Is there an unresolvable circular reference?
2017-11-23 12:30:04.064  INFO 20576 --- [  restartedMain] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2017-11-23 12:30:04.064  INFO 20576 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2017-11-23 12:30:04.080  INFO 20576 --- [  restartedMain] utoConfigurationReportLoggingInitializer : 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-11-23 12:30:04.080 ERROR 20576 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   screenshotsController defined in file [C:\Users\pupeno\Documents\Dashman\java\dashmanserver\out\production\classes\tech\dashman\server\controllers\ScreenshotsController.class]
┌─────┐
|  screenshotRepositoryImpl defined in file [C:\Users\pupeno\Documents\Dashman\java\dashmanserver\out\production\classes\tech\dashman\server\models\ScreenshotRepositoryImpl.class]
└─────┘
Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
  • `@Repository` is the correct annotation – Jens Nov 23 '17 at 12:27
  • see https://stackoverflow.com/questions/21323309/intellij-idea-shows-errors-when-using-springs-autowired-annotation – Jens Nov 23 '17 at 12:29
  • Why the downvotes? – Pablo Fernandez Nov 23 '17 at 12:32
  • @Jens `@Repository` doesn't work and that other question is just posting to `@Repository`. I clearly said that `@Repository` wasn't working in my initial question. – Pablo Fernandez Nov 23 '17 at 12:33
  • *doesn't work* is not an error description and also doesn't say that is not the right Annotation. As you can see in the error message`Requested bean is currently in creation: Is there an unresolvable circular reference` the bean will be found. – Jens Nov 23 '17 at 13:03
  • The IntelliJ warning is incorrect, it doesn't seem to identify repository custom implementations correctly. Tried a quick testapp and had the same incorrect hint, but application worked fine as expected. – Murka Nov 23 '17 at 13:38
  • @Murka: ah! thank you. Yes, my app works perfectly fine. Do you mind adding an answer with this information. – Pablo Fernandez Nov 23 '17 at 18:54

1 Answers1

2

What is happening?

Your dependencies form a cycle: ScreenshotRepository extends ScreenshotRepositoryCustom, but the ScreenshotRepositoryCustom implementation depends on ScreenshotRepository. Because of this cycle, none of the beans can complete their instantiation.

Proposed solution

Spring Data does not support injection via constructor in these scenarios. Attempting to do so will result in a dependency cycle error. To be able to inject ScreenshotRepository into ScreenShotRepositoryImpl, you'd need to do injection via field:

@Repository
public class ScreenshotRepositoryImpl implements ScreenshotRepositoryCustom {

    @Autowired
    ScreenshotRepository screenshotRepository ;

    ...

}
Sync
  • 3,571
  • 23
  • 30
  • I've never used an EntityManager so I'm trying to figure out how it's supposed to work. Using that code you pasted here, I'm getting this error: `Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null` – Pablo Fernandez Nov 23 '17 at 13:25
  • Also, is this answer incorrect then: https://stackoverflow.com/questions/11880924/how-to-add-custom-method-to-spring-data-jpa ? – Pablo Fernandez Nov 23 '17 at 13:27
  • If you really need to re-use methods from `ScreenshotRepository`, you might be better off creating a `ScreenshotService` that injects the `ScreenshotRepository` to avoid the cycle. – Wim Deblauwe Nov 23 '17 at 13:38
  • I updated my answer. I've read through the comments in your linked question. It seems you you are able to do so via field injection. However, I'm not sure if it works for Spring Boot 1.5+ as some comments seem to indicate it did not work for them. Can you give this a whirl? – Sync Nov 23 '17 at 13:55