How to prevent spring boot from auto creating instance of bean 'entityManagerFactory' at startup?
Asked Answered
P

2

8

I am working on a Spring boot application that uses Spring JPA with PostgreSQL. I am using @SpringBootTest(classes = <my package>.Application.class) to initialize my unit test for a controller class.

The problem is that this is causing the entityManagerFactory bean (and many other objects related to jpa, datasource, jdbc, etc.) to be created which is not needed for unit tests. Is there a way to prevent Spring from automatically creating these objects till they are actually used the first time?

I spent a lot of time trying to load up only the beans I need for my unit test but ran into many errors. I am relatively new to Spring and I am hoping someone else has run into this before...and can help. I can post code snippets if needed.

Update: I am not sure if I should edit or answer my own question...choosing to edit since I ended up changing my approach to unit tests. I added this to my test config class.

  @Configuration
  @ComponentScan(basePackages = {"api.controller", "api.config", "api.utils"})
  public class TestControllerConfig {
  }

and I mocked out the service and repository classes.

Papyrology answered 28/1, 2017 at 23:8 Comment(1)
If it is a unit test then you don't need @SpringBootTest else it is an integration test and you want a full context.House
B
10

You can disable auto configuration in spring-boot using exclude attribute of @EnableAutoConfiguration, as follows:

@Configuration
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class TestConfig {
}

From @EnableAutoConfiguration documentation:

If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead. Finally, you can also control the list of auto-configuration classes to exclude via the spring.autoconfigure.exclude property.

Bradlybradman answered 29/1, 2017 at 8:52 Comment(4)
I added a config class, TestControllerConfig, as suggested by you above. Then I modified my test class as shown below. The datasource and JPA beans still get created. And if I remove the @SpringBootTest annotation, I start getting errors (NoSuchBeanDefinitionException) for every bean I need for my test to work. @RunWith(SpringRunner.class) @SpringBootTest(classes = com.tgt.merch.eno.transferorder.api.Application.class) @ContextConfiguration(classes = com.tgt.merch.test.controller.config.TestControllerConfig.class) @AutoConfigureMockMvc public class HealthControllerTest {Papyrology
Since you have answered my original question and it makes sense to me, I am going to accept it even though I solved my issue a different way. I am new to posting in SO so I am hoping it is ok to do this.Papyrology
@Papyrology it's good if you share how you fixed it, will be helpful for future readers.Bradlybradman
I updated my original question with how I fixed it. Do you think I should add more details if it is not clear.Papyrology
D
0

It's also worth mentioning the @ConditionalOnProperty that accepts 3 parameters:

  • name: the name of the property you need to check (in your case was spring.jpa.enabled)

  • havingValue: this set to true to make sure the beans are instantiated only when the property set to true

  • matchIfMissing: this set the default value of the property in case you don't have it in the application.properties file.

Not to forget to also exclude the datasource, entitymanager and transaction manager configuration within the @SpringBootApplication list

@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
})
Delaine answered 18/9 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.