使用 Spring Boot 3 的本机映像出现“IllegalArgumentException:不是托管类型:MyEntity”问题

问题描述 投票:0回答:1

我的应用程序配置为支持多租户,因此我使用 LocalContainerEntityManagerFactoryBean 和 PlatformTransactionManager 在 MultiTenancyConfig 类中配置数据源。如何解决“IllegalArgumentException:不是托管类型:MyEntity”的问题?

请帮忙解决这个问题。

构建命令:C:pache-maven-3.9.0 in\mvn -Pnative clean install 执行命令:来自 VS 2022 的 x64 本机工具命令提示符运行命令:my-service.exe 操作系统:Windows 10 体系结构:系统类型基于 x64 的 PC GraalVM 架构和版本:graalvm-jdk-17_windows-x64_bin\graalvm-jdk-17.0.10+11.1 中 使用 Maven。

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example.services</groupId>
    <artifactId>my-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>my-service</name>
    <description>GraalVM Native image for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
        <commons-lang3.version>3.12.0</commons-lang3.version>
        <jackson-datatype-jsr310.version>2.15.2</jackson-datatype-jsr310.version>
        <springfox.version>3.0.0</springfox.version>
        <swagger-annotations-version>2.2.14</swagger-annotations-version>
        <json-simple.version>1.1.1</json-simple.version>
        <commons.io.version>2.12.0</commons.io.version>
        <apache.httpclient.version>4.5.14</apache.httpclient.version>
        <lombok.version>1.18.20</lombok.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>${jackson-datatype-jsr310.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.18.3</version>
        </dependency>
            <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>${springfox.version}</version>
        </dependency>
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>${swagger-annotations-version}</version>
        </dependency>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>3.2.3</version>
        </dependency>
        <!-- See Noteworthy section : https://github.com/spring-projects/spring-boot/releases/tag/v3.2.3
        https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-core -->
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.4.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>3.2.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.hibernate.orm</groupId>
                    <artifactId>hibernate-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.googlecode.json-simple</groupId>
            <artifactId>json-simple</artifactId>
            <version>${json-simple.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons.io.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${apache.httpclient.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.23.1-GA</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>native</id>
            <build>
                <pluginManagement>
                    <plugins>
                        <plugin>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                        <plugin>
                            <groupId>org.graalvm.buildtools</groupId>
                            <artifactId>native-maven-plugin</artifactId>
                            <version>0.9.25</version>
                            <executions>
                                <execution>
                                    <id>build-image</id>
                                    <goals>
                                        <goal>compile-no-fork</goal>
                                    </goals>
                                </execution>
                            </executions>
                        </plugin>
                    </plugins>
                </pluginManagement>
            </build>
        </profile>
    </profiles>

</project>

主要应用程序:

@SpringBootApplication
@ComponentScan(basePackages = "com.example.services")
public class MyServiceApplication implements WebMvcConfigurer {

    public static void main(String[] args) {
        MyServiceLogFormatter.updateLoggingHandler();
        new MyServiceApplication().startApplication(args);
    }

    private void startApplication(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(MyServiceApplication.class, args);
        applicationContext.registerShutdownHook();
    }
}

数据源配置类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.example.services.repository",
                        entityManagerFactoryRef="entityManagerFactory",
                        transactionManagerRef="transactionManager")
@EntityScan(
        basePackages = {"com.example.services.identity"}, 
        basePackageClasses = {MyEntity.class})
public class MultiTenancyConfig {
    
   public static final String SERVICE_CORE_IDENTITY_PKG 
                                    = "com.example.services.identity";
   
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Autowired DataSource dataSource,
            @Autowired MultiTenantConnectionProviderImpl multiTenantConnectionProvider,
            @Autowired TenantIdentifierResolverImpl currentTenantIdentifierResolver) {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource);
        em.setPackagesToScan(PW_SERVICE_CORE_IDENTITY_PKG);
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        
        Map<String, Object> properties = new HashMap<>();
        properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
        properties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
        properties.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, CamelCaseToUnderscoresNamingStrategy.class);
        properties.put(AvailableSettings.GENERATE_STATISTICS, BATCH_ENABLE);
        properties.put(AvailableSettings.STATEMENT_BATCH_SIZE, BATCH_SIZE);
        properties.put(AvailableSettings.ORDER_INSERTS, BATCH_ENABLE);
        properties.put(AvailableSettings.SHOW_SQL, false);
        em.setJpaPropertyMap(properties);
        return em;
    }

    @Bean
    PersistenceManagedTypes persistenceManagedTypes(ResourceLoader resourceLoader) {
        return new PersistenceManagedTypesScanner(resourceLoader)
                .scan(SERVICE_CORE_IDENTITY_PKG);
    }
    
   // @Configuration(proxyBeanMethods = false)
   // @ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class, EntityManagerFactory.class })
   // static class PersistenceManagedTypesConfiguration {

   //     @Bean
   //     @Primary
   //     @ConditionalOnMissingBean
   //     static PersistenceManagedTypes persistenceManagedTypes(BeanFactory beanFactory, ResourceLoader resourceLoader) {
   //         String[] packagesToScan = getPackagesToScan(beanFactory);
   //         return new PersistenceManagedTypesScanner(resourceLoader).scan(packagesToScan);
   //     }

   //     private static String[] getPackagesToScan(BeanFactory beanFactory) {
   //         List<String> packages = EntityScanPackages.get(beanFactory).getPackageNames();
   //         if (packages.isEmpty() && AutoConfigurationPackages.has(beanFactory)) {
   //             packages = AutoConfigurationPackages.get(beanFactory);
   //         }
   //         return StringUtils.toStringArray(packages);
   //     }
   // }
    
    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

实体类:

package com.example.services.identity;
@Entity
@Table(name = "MyEntity")
public class MyEntity { 
....

存储库:

package com.example.services.repository;
@Repository
public interface MyRepository extends JpaRepository<MyEntity, UUID>  {

    @Query(value = QueryConstants.GET_ALL_ACTIVE, nativeQuery = true)
    List<Object[]> findAllActive(@Param("status") String status, @Param("byOwner") String byOwner);
}

我在运行本机图像应用程序时启动时收到此错误:

[           main] w.s.c.ServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'myRepository': Error creating bean with name 'myRepository': Not a managed type: class com.example.services.identity.MyEntity

[           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'

2024-03-22T12:47:05.247+05:30 ERROR 25304 --- [/virts/ImgFleet/pw-service/1.0.0] [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myServiceImpl': Unsatisfied dependency expressed through field 'myRepository': Error creating bean with name 'myRepository': Not a managed type: class com.example.services.identity.MyEntity
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveValue(AutowiredFieldValueResolver.java:194) ~[na:na]
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveObject(AutowiredFieldValueResolver.java:154) ~[na:na]
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolve(AutowiredFieldValueResolver.java:143) ~[na:na]
        at com.example.services.MyServiceImpl__Autowiring.apply(MyServiceImpl__Autowiring.java:17) ~[na:na]
        at org.springframework.beans.factory.support.InstanceSupplier$1.get(InstanceSupplier.java:83) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:949) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1217) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1161) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[my-service.exe:6.1.4]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959) ~[my-service.exe:6.1.4]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[my-service.exe:6.1.4]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[my-service.exe:3.2.3]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[my-service.exe:3.2.3]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[my-service.exe:3.2.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[my-service.exe:3.2.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[my-service.exe:3.2.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[my-service.exe:3.2.3]
        at comcom.example.services.MyServiceApplication.startApplication(MyServiceApplication.java:50) ~[my-service.exe:na]
        at com.example.services.MyServiceApplication.main(MyServiceApplication.java:44) ~[my-service.exe:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myRepository': Not a managed type: com.example.services.identity.MyEntity
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1443) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.aot.AutowiredFieldValueResolver.resolveValue(AutowiredFieldValueResolver.java:188) ~[na:na]
        ... 24 common frames omitted
Caused by: java.lang.IllegalArgumentException: Not a managed type: class com.example.services.identity.MyEntity
        at org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl.managedType(JpaMetamodelImpl.java:193) ~[na:na]
        at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.managedType(MappingMetamodelImpl.java:468) ~[na:na]
        at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.managedType(MappingMetamodelImpl.java:98) ~[na:na]
        at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:82) ~[my-service.exe:3.2.3]
        at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:69) ~[my-service.exe:3.2.3]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:246) ~[my-service.exe:3.2.3]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:211) ~[my-service.exe:3.2.3]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:194) ~[my-service.exe:3.2.3]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:1) ~[my-service.exe:3.2.3]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:317) ~[my-service.exe:3.2.3]
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:279) ~[my-service.exe:3.2.3]
        at org.springframework.data.util.Lazy.getNullable(Lazy.java:135) ~[my-service.exe:3.2.3]
        at org.springframework.data.util.Lazy.get(Lazy.java:113) ~[my-service.exe:3.2.3]
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:285) ~[my-service.exe:3.2.3]
        at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:132) ~[my-service.exe:3.2.3]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1833) ~[my-service.exe:6.1.4]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782) ~[my-service.exe:6.1.4]
        ... 34 common frames omitted
spring-boot spring-data-jpa multi-tenant graalvm-native-image
1个回答
0
投票

我可以在互联网上找到修复程序https://github.com/DigitalMediageek/aot-database-issue

类似的 github 有一个示例项目只关注这个问题,我的代码更改有额外的更改,这也处理了多租户问题。

必须使用实体管理器和事务管理器更改数据库配置:

@Configuration
@EnableJpaRepositories(basePackages = {
    "com.example.services.repository" },
    entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager")
public class MultiTenancyConfig {
   
    /**
     * Configures the entity manager factory for multi-tenancy.
     * @return the configured entity manager factory
     */
   @Bean("entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Autowired DataSource dataSource,
            @Qualifier("entityManagerFactoryBuilder") EntityManagerFactoryBuilder builder,
            @Qualifier("persistenceManagedTypes")PersistenceManagedTypes persistenceManagedTypes) {
        return builder.dataSource(dataSource)
        .packages(MyEntity.class)
        .managedTypes(persistenceManagedTypes).build();
    }
   
   @Bean("entityManagerFactoryBuilder")
   EntityManagerFactoryBuilder entityManagerFactoryBuilder(
           @Autowired MultiTenantConnectionProviderImpl multiTenantConnectionProvider,
           @Autowired TenantIdentifierResolverImpl currentTenantIdentifierResolver,
           ObjectProvider<PersistenceUnitManager> persistenceUnitManager) {
       Map<String, Object> jpaProperties = new HashMap<>();
       jpaProperties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
       jpaProperties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
       jpaProperties.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, CamelCaseToUnderscoresNamingStrategy.class);
       jpaProperties.put(AvailableSettings.SHOW_SQL, false);
       
       return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), jpaProperties,
               persistenceUnitManager.getIfAvailable());
   }

   @Bean("transactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
   
   @Bean("persistenceManagedTypes")
   PersistenceManagedTypes persistenceManagedTypes(ResourceLoader resourceLoader) {
       return new PersistenceManagedTypesScanner(resourceLoader)
               .scan("com.example.services.identity");
   }

}
© www.soinside.com 2019 - 2024. All rights reserved.