0

I am getting this exception while testing my Controller class

Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!
    at org.springframework.util.Assert.notEmpty(Assert.java:450)
    at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.<init>(JpaMetamodelMappingContext.java:54)
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:88)
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:43)
    at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:141)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1761)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1698)

My controller test class looks like this

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = {SensorController.class}, secure = false)
public class SensorControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private SensorService sensorService;

    .....
}

My Bootstrap class

@SpringBootApplication(scanBasePackages = "com.javadroider")
@RestController
@EntityScan("com.javadroider.notifier.commons.model")
@EnableJpaRepositories(basePackages = "com.javadroider.notifier")
public class NotifierApplication {

    @GetMapping("/")
    public String home(){
        return "Welcome to Notifier";
    }

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

My dependencies look like this

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
            <scope>runtime</scope>
        </dependency>
</dependencies>

When I remove @EnableJpaRepositories from my Bootstrap class then controller test will be successful. But application will not start. It will fail with NoSuchBeanDefinitionException.

I am not sure if it is something related to the way I have configured my application. All my repository & model classes are in commons module and I am referring to them in my main aplpication.

My query is similar to https://github.com/spring-projects/spring-boot/issues/6844

IllegalArgumentException: At least one JPA metamodel must be present didn't solve my problem

Javadroider
  • 2,280
  • 1
  • 22
  • 45
  • please, add the dependencies you are using – Andrew Tobilko May 09 '18 at 09:00
  • look at this: https://stackoverflow.com/questions/40738818/illegalargumentexception-at-least-one-jpa-metamodel-must-be-present – Andrew Tobilko May 09 '18 at 09:01
  • Possible duplicate of [IllegalArgumentException: At least one JPA metamodel must be present](https://stackoverflow.com/questions/40738818/illegalargumentexception-at-least-one-jpa-metamodel-must-be-present) – Mehraj Malik May 09 '18 at 09:02
  • @MehrajMalik https://stackoverflow.com/questions/40738818/illegalargumentexception-at-least-one-jpa-metamodel-must-be-present didnt solve my problem. – Javadroider May 09 '18 at 09:05

1 Answers1

0

The @WebMvcTest annotation does not auto configure any repositories or JPA layer beans for you because it is primarily focused on testing just the Controller level.

Your main class NotifierApplication is trying to do too much. See the single responsibility principle for good programming practices: https://en.wikipedia.org/wiki/Single_responsibility_principle

The main class should be used just to define your application it should not itself be a @RestController. Create a separate class, NotifierController, for example and make this your @RestController with your endpoints defined there:

@RestController 
public class NotifierController {

    @GetMapping("/")
    public String home(){
        return "Welcome to Notifier";
    }

}

and keep this separate from your main class:

@SpringBootApplication(scanBasePackages = "com.javadroider")
@EntityScan("com.javadroider.notifier.commons.model")
@EnableJpaRepositories(basePackages = "com.javadroider.notifier")
public class NotifierApplication {

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

The reason it was failing the way you had it is that your WebMvcTest was trying to scan for JPA repositories and entities due to the annotations on the main class but this is not configured for WebMvcTests.

Plog
  • 9,164
  • 5
  • 41
  • 66