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

Posted

技术标签:

【中文标题】必须存在至少一个 JPA 元模型【英文标题】:At least one JPA metamodel must be present 【发布时间】:2018-10-19 07:52:37 【问题描述】:

我在测试我的 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;

    .....

我的引导类

@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 失败。

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

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

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

【问题讨论】:

请添加您正在使用的依赖项 看看这个:***.com/questions/40738818/… IllegalArgumentException: At least one JPA metamodel must be present的可能重复 @MehrajMalik ***.com/questions/40738818/… 没有解决我的问题。 【参考方案1】:

@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 进行配置。

【讨论】:

以上是关于必须存在至少一个 JPA 元模型的主要内容,如果未能解决你的问题,请参考以下文章

使用@WebMvcTest 获取“必须存在至少一个 JPA 元模型”

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

“IllegalArgumentException:必须存在至少一个 JPA 元模型” - 尝试将应用程序同时连接到 mongo 和 sql 时

如何修复“加载应用程序上下文失败,至少必须存在 1 个 JPA 元模型”

用Eclipse生成JPA元模型

JPA 元模型生成缺少属性