如何使用外部Jar中的JPA实体类构建Micronaut项目
现有Micronaut项目计划通过pom.xml引入封装在外部Jar中的Spring JPA实体类作为依赖完成项目构建,但构建、运行过程中始终抛出如下核心错误:
Caused by: io.micronaut.context.exceptions.ConfigurationException: Entities not found for JPA configuration: 'default' within packages [packageName]
已尝试的无效方案
- 在
pom.xml中将实体所在Jar包以compile作用域添加为项目依赖,问题未解决 - 参照Micronaut官方文档说明,新建类添加
@Introspected(classes = User.class)注解以加载外部Jar中预编译的User.class实体类,问题未解决 - 尝试在类上同时标注
@Entity与@Introspected注解以标记实体类,问题未解决 - 尝试自定义AnnotationMapper实现
javax.persistence.Entity对应包的自动扫描映射,问题未解决 - 若移除
micronaut-data-spring-jpa依赖,项目将不再校验实体类存在,但会导致Micronaut对接Spring JPA Repository的自动迁移逻辑报错,无法使用
补充信息
- 项目内部未定义任何
@Entity实体类,建设目标是复用自行封装的Spring JPA实体类外部Jar,供多个应用统一引用 - 执行
mvn clean install或直接运行项目时的完整异常信息如下:
io.micronaut.context.exceptions.BeanInstantiationException:
Bean definition [org.hibernate.SessionFactory] could not be loaded: Error instantiating bean of type [org.hibernate.boot.SessionFactoryBuilder]
配套错误提示:
Entities not found for JPA configuration: 'default' within packages [packageName]. Check that you have correctly specified a package containing JPA entities within the "jpa.default.entity-scan.packages" property in your application configuration and that those entities are either compiled with Micronaut or a build time index produced with @Introspected(packages="foo.bar", includedAnnotations=Entity.class) declared on your Application class
异常调用链路:Path Taken: SessionFactory.hibernateSessionFactory(SessionFactoryBuilder sessionFactoryBuilder) --> SessionFactory.hibernateSessionFactory([SessionFactoryBuilder sessionFactoryBuilder]) --> SessionFactoryBuilder.hibernateSessionFactoryBuilder([MetadataSources metadataSources],ValidatorFactory validatorFactory,Interceptor hibernateInterceptor)
Micronaut基于编译时生成元数据实现Bean扫描、JPA实体识别,外部独立封装的Spring JPA实体Jar未经过Micronaut注解处理器处理,不会自带Micronaut所需的实体索引、反射访问元数据。之前尝试的@Introspected(classes = User.class)方式仅会生成单个类的基础反射索引,不会触发JPA实体所需的关联元数据生成;单独给类补注注解、自定义注解映射的方式也无法覆盖编译阶段的实体元数据生成逻辑,因此会持续报实体找不到的错误。
- 在项目启动主类(标注
@Application的入口类)上添加包级别@Introspected注解,覆盖外部Jar的实体根包,同时指定扫描JPA实体注解:import io.micronaut.core.annotation.Introspected; import io.micronaut.runtime.Micronaut; import javax.persistence.Entity; // 替换为外部Jar中实体类所在的实际根包 @Introspected( packages = "com.yourexternal.entity.package", includedAnnotations = Entity.class ) public class Application { public static void main(String[] args) { Micronaut.run(Application.class, args); } } - 核对项目配置文件(
application.yml/application.properties)中的JPA实体扫描路径,确保和上述注解指定的实体包完全一致,以yaml配置为例:jpa: default: entity-scan: packages: - 'com.yourexternal.entity.package' - 调整
pom.xml中maven编译插件配置,开启外部注解扫描参数,确保编译阶段能读取到外部Jar中的实体类信息:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <!-- 保留原有Micronaut、Micronaut Data相关注解处理器依赖 --> <path> <groupId>io.micronaut.data</groupId> <artifactId>micronaut-data-processor</artifactId> <version>${micronaut.data.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-Amicronaut.scan.external.annotations=true</arg> </compilerArgs> </configuration> </plugin> - 执行
mvn clean compile重新触发全量注解处理,确认编译输出的target/classes/META-INF/micronaut/路径下生成了外部实体对应的Bean定义文件后,再启动项目即可正常加载外部Jar中的JPA实体。
内容的提问来源于stack exchange,提问作者Miguel Jr. Bermundo

