Spring Boot startup behavior

Field required a bean of type that could not be found.

Encountered this while using spring data jpa and the entities were defined in a common library. So the package names of the jpa repositories don’t match that of the main Application class in the spring boot application.

How do we solve this?

You have to enable the repositories outside of your Spring Boot application with @EnableJpaRepositories explicitly.

In the class with the @SpringBootApplication annotation, we have to tell it where to look for the entities.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.mycompany.jparepositories"})
public class SpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication.class, args);
    }

}

Not a managed type

Encountered this while using spring data jpa and the entities were defined in a common library. So the package names of the entities don’t match that of the main Application class in the spring boot application.

How do we solve this?

In the class with the @SpringBootApplication annotation, we have to tell it where to look for the entities.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.mycompany.jparepositories.entities"})
@EntityScan(basePackages = {"com.mycompany.jparepositories.entities"})
public class SpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication.class, args);
    }

}

Make sure that the components from common libraries are included in spring component scan

If there are components defined in the common libraries, and if those components need to be used in the application, do it using this:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@ComponentScan(basePackages = {"com.mycompany.commonlibrarypackagename"})
@ServletComponentScan(basePackages = {"com.mycompany.commonlibrarypackagename"})
public class SpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication.class, args);
    }

}

Make sure that the components from common libraries are excluded from spring component scan

Why would you need this?

Sometimes, you may be using a custom library, and there may be some code in the library (like jpa code to connect to a database) and when your application has a dependency on that library, but there are some components that you do not want to get scanned by spring when starting up your application.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.library.mainpackage" },
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.library.mainpackage.package.to.be.ignored.*..*"))
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Excluding certain auto configured features from the application

Why would you need this?

Sometimes, you may be using a custom library, and there may be some code in the library (like jpa code to connect to a database) and when your application has a dependency on that library, but you do not want to use the JPA code, you need to disable the auto configuration.

// Main class definition

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.library.mainpackage" },
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.library.mainpackage.package.to.be.ignored.*..*"))
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Spring auto configuration

Correct the classpath of your application so that it contains compatible versions of the classes

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector and org.springframework.beans.factory.config.ConfigurableListableBeanFactory

Encountered this while using spring data jpa and the entities were defined in a common library. When your application has a dependency on that library but there are dependencies in your application and there are version conflicts:

Error at the console:

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

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector.detect(AnnotationDependsOnDatabaseInitializationDetector.java:36)

The following method did not exist:

    'java.lang.annotation.Annotation org.springframework.beans.factory.config.ConfigurableListableBeanFactory.findAnnotationOnBean(java.lang.String, java.lang.Class, boolean)'

The calling method's class, org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector, was loaded from the following location:

    jar:file:/home/kmj/.m2/repository/org/springframework/boot/spring-boot/2.6.4/spring-boot-2.6.4.jar!/org/springframework/boot/sql/init/dependency/AnnotationDependsOnDatabaseInitializationDetector.class

The called method's class, org.springframework.beans.factory.config.ConfigurableListableBeanFactory, is available from the following locations:

    jar:file:/home/kmj/.m2/repository/org/springframework/spring-beans/5.3.13/spring-beans-5.3.13.jar!/org/springframework/beans/factory/config/ConfigurableListableBeanFactory.class

The called method's class hierarchy was loaded from the following locations:

    org.springframework.beans.factory.config.ConfigurableListableBeanFactory: file:/home/kmj/.m2/repository/org/springframework/spring-beans/5.3.13/spring-beans-5.3.13.jar


Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector and org.springframework.beans.factory.config.ConfigurableListableBeanFactory

Disconnected from the target VM, address: '127.0.0.1:46807', transport: 'socket'

Process finished with exit code 1

How do we fix this?

You could be loading both 2.6.4 and 2.6.5 versions of spring boot. Remove the version numbers in the dependencies section. The parent pom manages the dependencies for you. Pay attention to the versions of spring that is being used in the various applications.


Links to this note