I'm currently developing AWS Lambda functions using Spring Boot 3 native image cloud functions and JPA. My JPA entities are housed in a separate common library, which I've incorporated into my project as a Maven dependency. The following code snippet is used to scan entities within the common library package:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource);
    em.setPackagesToScan(new String[] { "com.bittsi.entity" });
    em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    return em;
}

When executing the application in standard mode as a Spring Boot application, everything works correctly and the entities are recognized. However, when running the Spring native image executable artifact, I encounter an error: Caused by: java.lang.IllegalArgumentException: Not a managed type: com.bittsi.entity.XXX.

Could this issue stem from missing native build configurations, or is it a bug?

Comment From: wilkinsona

You need to define a PersistenceManagedTypes bean that can be used during AOT processing to prepare the native image. Typically, Spring Boot's auto-configuration defines one for you but it backs off when you define your own LocalContainerEntityManagerFactoryBean.

I would recommend using the auto-configuration if you can. For example, by using @EntityScan to configure the scanning of com.bittsi.entity.

If you want or need to configure things manually, you can take some inspiration from the code in org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.PersistenceManagedTypesConfiguration.

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Comment From: MondalSubhajit

My application is configured to support multitenancy, hence I am configuring the datasource in MultiTenancyConfig class with the LocalContainerEntityManagerFactoryBean and PlatformTransactionManager . How can I fix the issue of "IllegalArgumentException: Not a managed type: MyEntity" ?

Please help to fix this.

Build Command : C:\apache-maven-3.9.0\bin\mvn -Pnative clean install Execution Command : From x64 Native Tools Command Prompt for VS 2022 running command : my-service.exe OS : Windows 10 Architecture: System Type x64-based PC GraalVM arch and version : graalvm-jdk-17_windows-x64_bin\graalvm-jdk-17.0.10+11.1\bin Using 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>

main app :

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

Datasource configuration class:

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

Entity class:

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

Repository :

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

I am getting this error during startup while running my native image app :

[           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

Comment From: wilkinsona

@MondalSubhajit please ask questions on Stack Overflow.

Comment From: MondalSubhajit

I am getting this error during startup while running my native image app :

Thanks for your response, I have asked the question in Stack Overflow. https://stackoverflow.com/questions/78206016/issue-of-illegalargumentexception-not-a-managed-type-myentity-for-native-ima