Spring Boot - Spring Data giving Error creating bean with name 'dataSourceInitializerPostProcessor' error - spring-boot

I have a spring boot spring data application. This was working fine when my repository extended CrudRepository. To get dynamic querying, I extended QueryByExampleExecutor. After extending QueryByExampleExecutor, and run the mvn spring-boot:run, I am getting the below error:
***An exception occured while running. null: InvocationTargetException: Error creating bean with name 'dataSourceInitializerPostProcessor': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.beans.factory.BeanFactory org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor.beanFactory; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeProfileRepository': Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)***
Repository Class:
#Transactional
#Repository
public interface EmployeeProfileRepository extends CrudRepository<EmployeeProfile, Long>, QueryByExampleExecutor<EmployeeProfile> {
}
Service Class:
#Service
public class EmployeeProfileService {
#Autowired
private EmployeeProfileRepository empProfileRepository;
public List<EmployeeProfile> searchEmployees(Long id, String firstName, String lastName) {
List<EmployeeProfile> employees = new ArrayList<>();
EmployeeProfile emp = new EmployeeProfile();
emp.setId(id);
emp.setFirstName(firstName);
emp.setLastName(lastName);
Example<EmployeeProfile> example = Example.of(emp);
Iterable<EmployeeProfile> iterable = empProfileRepository.findAll(example);
iterable.forEach(employees::add);
return employees;
}
}
Application class:
#Configuration
#EnableAutoConfiguration
#EnableJpaRepositories("com.employee.dao")
#ComponentScan("com.employee")
#EntityScan("com.employee.dto")
public class Application extends SpringBootServletInitializer {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected final SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}

Related

ApplicationEventPublisher is not being autowired into Component

I have a Spring Boot app and #Component class which looks like:
#Component
public class CustomEvent {
#Autowired
ApplicationEventPublisher publisher;
#PreRemove
public void onItemDelete(Object entity) {
System.out.println(" =======PUBLISH====== " + entity);
publisher.publishEvent(new EntityDeleteEvent<>(entity));
}
}
When it goes to run above method the first line is printed with proper entity but the publisher.publishEvent line throws a NullPointerException. I suppose it that the ApplicationEventPublisher is not being #Autowired but couldn't find why. Other #Components which are in the app are found by #ComponentScanner.
Of course in my entity this CustomEvent is registered:
#Entity
#EntityListeners(
CustomEvent.class
)
#Data
#AllArgsConstructor
public class Item
The exact error which is thrown looks like:
2017-10-26 16:46:06.190 ERROR 10176 --- [io-8091-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.inventory.events.CustomEvent.onItemDelete(CustomEvent.java:19)
Do you have any suggestion why publisher is null?
The initialisation of ApplicationEventPublisher doesn't happen OR will remain null, if you have created the CustomeEvent without the help of Bean (like CustomEvent event = new CustomEvent().
Instead, declare the CustomEvent as bean in your configuration (Spring) and get the CustomEvent using application context.
If CustomEvent is in the Spring's package scan, then I don't know.
But, there is an additional solution.
Create a class to instantiate spring managed class, but by ApplicationContext.
1 - Create the class below:
public class AppContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
#Override
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
context = appContext;
}
public static ApplicationContext getApplicationContext() {
return context;
}
public static <T> T getBean(Class<T> classe) {
return context.getBean(classe);
}
}
2 - Instance class as below:
public class CustomEvent {
private ApplicationEventPublisher publisher;
#PreRemove
public void onItemDelete(Object entity) {
System.out.println(" =======PUBLISH====== " + entity);
getApplicationEventPublisher().publishEvent(new EntityDeleteEvent<>(entity));
}
private ApplicationEventPublisher getApplicationEventPublisher() {
return AppContextUtil.getBean(ApplicationEventPublisher.class);
}
}

MongoDB and Spring JPA integration is throwing error

I am trying to integrate Spring JPA with MongoDB. My intention is to just retrieve data from mongo DB. I am getting the below error while injecting my repository.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.org.coop.society.data.mongo.repositories.MaterialMasterRepository com.org.coop.security.service.MongoService.materialMasterRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'materialMasterRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
My configuration snippet is given below.
TestMongoDBConfig.java
#Configuration
#EnableMongoRepositories(basePackages = {"com.abc.data.mongo.repositories"})
#ComponentScan(basePackages = "com.abc")
#PropertySource("classpath:applicationTest.properties")
public class TestMongoDBConfig extends AbstractMongoConfiguration {
#Autowired
private Environment env;
#Override
protected String getDatabaseName() {
return "retail";
}
#Override
#Bean
public MongoClient mongo() throws Exception {
MongoClient client = new MongoClient("localhost", 27017);
return client;
}
#Override
protected String getMappingBasePackage() {
return "com.abc.data.mongo.entities";
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), getDatabaseName());
}
}
MaterialMaster.java in com.abc.data.mongo.entities package
#Document(collection = "materialMaster")
public class MaterialMaster {
#Id
private Long materialId;
#Field
private String name;
MaterialMasterRepository.java in com.abc.data.mongo.repositories package
public interface MaterialMasterRepository extends MongoRepository<MaterialMaster, Long> {
}
MongoService.java in com.abc.service package
#Service
public class MongoService {
#Autowired
private MaterialMasterRepository materialMasterRepository;
public void getMaterials() {
List<MaterialMaster> materials = materialMasterRepository.findAll();
System.out.println(materials);
}
}
Junit class looks like below
#RunWith(SpringJUnit4ClassRunner.class)
#ComponentScan(basePackages = "com.abc")
#ContextHierarchy({
#ContextConfiguration(classes={TestMongoDBConfig.class})
})
public class ModuleWSTest {
#Autowired
private MongoService mongoService;
#Test
public void testModule() {
mongoService.getMaterials();
}
}
I have tried all possible changes (as per my knowledge) but no luck. Any help is really appreciated.
The error message is little confusing. I was using latest spring-data-mongodb (1.8.4.RELEASE). Once I downgraded the dependency to 1.6.0.RELEASE then the above configuration started working.

Spring Resource Assembler throwing NoSuchBeanDefinitionException

I am using ResourceAssemblerSupport from spring-hateoas in a spring boot Application
I have created the assembler like below:
public class MemberResourceAssembler extends ResourceAssemblerSupport<Member, MemberResource>{
public MemberResourceAssembler(Class<?> controllerClass, Class<MemberResource> resourceType) {
super(controllerClass, resourceType);
}
#Override
public MemberResource toResource(Member member) {
MemberResource memberResource=new MemberResource();
memberResource.setStatus(member.getStatus());
memberResource.setHeight(member.getHeight());
memberResource.setIs_veg(member.getIs_veg());
memberResource.setRace(member.getRace());
memberResource.setWeight(member.getWeight());
return memberResource;
}
}
And the reource class as below:
public class MemberResource extends ResourceSupport implements Serializable{
//relevant code here
}
The domain class is as below:
#Document(collection="Member")
public class Member {
//relevant code here
}
The repository class is as below:
public interface MemberRepository extends PagingAndSortingRepository<Member,Integer> {
Page<Member> findByStatusContainsIgnoreCase(#Param("q") String status, Pageable pageable);
}
Now I am trying to use in my controller as below:
#RestController
#RequestMapping("/members")
public class MemberController {
#Autowired
private MemberRepository memberRepository;
#Autowired
private MemberResourceAssembler assembler;
#RequestMapping(value = "/search", method = RequestMethod.GET)
public PagedResources<MemberResource> search(#RequestParam("status") String status, #PageableDefault Pageable pageable,
PagedResourcesAssembler<Member> pagedAssembler) {
Page<Member> members = memberRepository.findByStatusContainsIgnoreCase(status, pageable);
return pagedAssembler.toResource(members, assembler);
}
}
I am getting below exception:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.sg.resources.MemberResourceAssembler] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Using spring-hateoas version 0.19.0.RELEASE.All the dependencies are coming through starters of Spring Boot 1.3.0.RELEASE
There is a spring boot Application class in the parent package of the Controller class.The Autowire annotation on the repository is working properly.
Your MemberResourceAssembler should be annotated as #Component to make it available for autowiring.
I added a bean definition in the Application.class which solved the issue
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public MemberResourceAssembler memberResourceAssembler() {
return new MemberResourceAssembler(MemberController.class, MemberResource.class);
}
}

Unable to autowire dozer Mapper in component class in spring boot

I am new to Spring Boot. I was trying to develop small application in spring boot mvc with neo4j database. Following is my Server
#Configuration
#ComponentScan({ "myproject" })
#EnableAutoConfiguration
#EnableNeo4jRepositories(basePackages = "myproject")
public class Server extends Neo4jConfiguration implements CommandLineRunner
{
public Server()
{
setBasePackage("myproject");
}
#Bean
SpringRestGraphDatabase graphDatabaseService()
{
return new SpringRestGraphDatabase("http://localhost:7474/db/data");
}
#Bean
Mapper mapper()
{
return new DozerBeanMapper();
}
public void run(String... args) throws Exception
{
}
public static void main(String[] args) throws Exception
{
SpringApplication.run(Server.class, args);
}
}
Following is my main class
#Configuration
#ComponentScan({ "myproject.business" })
#EnableNeo4jRepositories(basePackages = "myproject")
public class MainWithStructure extends Neo4jConfiguration implements CommandLineRunner
{
#Autowired
private MyService myService;
public MainWithStructure()
{
setBasePackage("myproject");
}
#Bean
SpringRestGraphDatabase graphDatabaseService()
{
return new SpringRestGraphDatabase("http://localhost:7474/db/data");
}
.......
......
public static void main(String[] args) throws Exception
{
FileUtils.deleteRecursively(new File("accessingdataneo4j.db"));
SpringApplication app = new SpringApplication(MainWithStructure.class);
app.setWebEnvironment(false);
app.run(args);
}
}
Following is my Component class
#Component
public class MyService
{
#Autowired
private Mapper mapper; //Fails to autowire org.dozer.Mapper
.....
}
Following is my Controller class
#RestController
#RequestMapping("/rest")
public class MyController
{
#Autowired
private Mapper mapper; //autowire sucess org.dozer.Mapper
}
I got following Exception when I run main class MainWithStructure
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mainWithStructure': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myproject.business.MyService myproject.main.MainWithStructure.MyService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.dozer.Mapper myproject.business.MyService.mapper; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.dozer.Mapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Following is my project structure
demo_project
src/main/java
---myproject.main
------MainWithStructure.java
------Server.java
---myproject.business
------MyService.java
---myproject.rest
------MyController.java
If I autowire org.dozer.Mapper in Controller, it sucessfuly autowired it. BUT if I autowire org.dozer.Mapper in Component class it fails to autowire.
Why it is failing to autowire org.dozer.Mapper only on Component class?
Please make me correct if I wrong. Thank you :)
Your Server is not in one of the packages that you #ComponentScan, so the Mapper is indeed not a bean. Try removing the explicit package from the #ComponentScan (since everything is in a subpackage of the main class that will pick up all the components).
You can add #SpringBootApplication in your main class which has #ComponentScan
which will scan all your sub components in project.

No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' is defined

i am trying to run full package of junit test classes, and i have an audit classes for my domain classes as follows:
#PrePersist
public void prePersist(AuditableEntity e) {
UserService userService = SpringBeanFactory.getBean(UserService.class);
// some auditing here
}
- SpringBeanFactory class:
public class SpringBeanFactory {
private static ApplicationContext applicationContext;
public static <T> T getBean(final String name, final Class<T> requiredType) {
T bean = null;
if (applicationContext != null) {
bean = applicationContext.getBean(name, requiredType);
}
return bean;
}
public static <T> T getBean(final Class<T> requiredType) {
T bean = null;
if (applicationContext != null) {
bean = applicationContext.getBean(requiredType);
}
return bean;
}
public static void setApplicationContext(final ApplicationContext applicationContext) {
if (SpringBeanFactory.applicationContext == null) {
SpringBeanFactory.applicationContext = applicationContext;
}
}
}
-Test class config:
#Autowired
private ApplicationContext applicationContext;
#Before
public void before() throws Exception {
SpringBeanFactory.setApplicationContext(applicationContext);
}
-SpringTestingConfig class:
#Configuration
#ComponentScan(basePackages = "com.myapp.data", excludeFilters = { #Filter(Configuration.class) })
#PropertySource("classpath:/test.properties")
#Profile("test")
public class SpringTestingConfig {
private static Logger log = (Logger)LoggerFactory.getLogger(SpringTestingConfig.class);
#Autowired
private ApplicationContext applicationContext;
#Bean
public DataSource XdataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
if(log.isDebugEnabled()) log.debug("profile.name", "test");
System.setProperty("profile.name", "test");
dataSource.setDriverClassName("org.h2.Driver");
String schemaName = ConfigurationUtil.config().getString("db.schema.name").toLowerCase();
log.debug("SCHEMA IS " + schemaName);
String url = "jdbc:h2:mem:test;MODE=Mysql;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS " +schemaName +"\\;" + "SET SCHEMA "+schemaName;
dataSource.setUrl(url);
//dataSource.setUrl("jdbc:h2:mem:test;MODE=Mysql;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS " + schemaName);
dataSource.setUsername("sa");
//use your own local mysql in tests here...
// dataSource.setDriverClassName("com.mysql.jdbc.Driver");
// dataSource.setUrl("jdbc:mysql://localhost:3306/mv_tests?characterEncoding=UTF-8");
// dataSource.setUsername("tomcat");
// dataSource.setPassword("tomcat");
//
return dataSource;
}
#Bean
public DataSource dataSource() {
SpringBeanFactory.setApplicationContext(applicationContext);
LoggerUtils.setAllApplicationLogs("DEBUG");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
if(log.isDebugEnabled()) {
log.debug("profile.name", "test");
}
System.setProperty("profile.name", "test");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
String schemaName = ConfigurationUtil.config().getString("db.schema.name");
String username = ConfigurationUtil.config().getString("db.username");
String password = ConfigurationUtil.config().getString("db.password");
if( log.isDebugEnabled() ) {
log.debug( "SCHEMA IS " + schemaName );
log.debug( "Username IS " + username );
log.debug( "Password IS " + password );
}
dataSource.setUrl("jdbc:mysql://localhost:3306/"+schemaName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
-Test class annotations:
#RunWith(SpringJUnit4ClassRunner.class)
#TestExecutionListeners({ WebContextTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class })
#ActiveProfiles("test")
#DirtiesContext
#ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = { SpringConfig.class, SpringTestingConfig.class, SpringLocalContainerJPAConfig.class, CustomConfiguration.class })
#Transactional
when my test method tries to save an entity, it makes call to PrePersist method which in turn makes call to the getting spring service:
UserService userService = SpringBeanFactory.getBean(UserService.class);
which in turns produces the following exception:
Error creating bean with name 'userService':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private com.motivosity.data.repository.UserRepository com.motivosity.service.impl.UserServiceImpl.userRepository;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepositoryImpl':
Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'springLocalContainerJPAConfig': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field:
javax.sql.DataSource com.motivosity.data.config.SpringLocalContainerJPAConfig.dataSource;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'springTestingConfig': Initialization of bean failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.cache.annotation.ProxyCachingConfiguration':
Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' is defined
i have to mention that this exception occurs when running full package of test classes, but when running this test class separately no exception is produced.
BTW, i am using spring 3.2.3.RELEASE
UPDATE: when i upgraded the spring version to latest release 4.0.3, i am getting a new exception on the same get UserService line:
org.springframework.context.support.GenericApplicationContext#3aa54263 has been closed already
please advise how to fix this exception.
When you annotate a test class or test method with #DirtiesContext, you are telling Spring to close the ApplicationContext after that test class or method. Thus, if you later attempt to retrieve a bean from a closed context you will get an exception like you're seeing.
My guess is that you are using #DirtiesContext in other test classes within your test suite, and a result the logic in SpringBeanFactory.setApplicationContext() is broken since it can potentially maintain a reference to a closed context. Thus, you'll need allow the current ApplicationContext to be set for each test. In other words, remove the null-check like follows
public static void setApplicationContext(final ApplicationContext applicationContext) {
// always set the current context
SpringBeanFactory.applicationContext = applicationContext;
}
Hope this helps!
- Sam (author of the Spring TestContext Framework)

Resources