必须至少存在一个JPA元模型

时间:2018-05-09 08:54:32

标签: java spring spring-boot spring-data-jpa

我在测试Controller类时遇到此异常

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)

我的控制器测试类看起来像这样

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

    @Autowired
    private MockMvc mvc;

    @MockBean
    private SensorService sensorService;

    .....
}

My Bootstrap课程

@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);
    }
}   

我的依赖项看起来像这样

<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>

当我从Bootstrap类中删除@EnableJpaRepositories时,控制器测试将成功。但是申请不会开始。它将失败NoSuchBeanDefinitionException

我不确定它是否与我配置应用程序的方式有关。我所有的存储库和模型类在公共模块中,我在主要的应用中指的是它们。

我的查询类似于https://github.com/spring-projects/spring-boot/issues/6844

IllegalArgumentException: At least one JPA metamodel must be present没有解决我的问题

1 个答案:

答案 0 :(得分:0)

@WebMvcTest注释不会为您自动配置任何存储库或JPA图层bean,因为它主要侧重于仅测试控制器级别。

你的主类NotifierApplication试图做太多。请参阅良好编程实践的单一责任原则:https://en.wikipedia.org/wiki/Single_responsibility_principle

主类应仅用于定义您的应用程序,它本身不应该是@RestController。例如,创建一个单独的类NotifierController,并将其设为@RestController,并在其中定义端点:

@RestController 
public class NotifierController {

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

}

并将其与主要类别分开:

@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);
    }
} 

它失败的原因是你的WebMvcTest由于主类上的注释而试图扫描JPA存储库和实体,但是没有为WebMvcTests配置。