我的应用程序配置为支持多租户,因此我使用 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
我可以在互联网上找到修复程序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");
}
}