kazuki43zoo / mybatis-spring-native

The experimental project that the MyBatis integration with Spring Native feature

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot bind configuration properties to MybatisProperties

kazuki43zoo opened this issue · comments

Cannot bind configuration properties to MybatisProperties, if mapper was scanned (can bind, if mapper not scanned).

I add configuration property of mybatis-spring-boot as follows:

e.g.)

mybatis.configuration.map-underscore-to-camel-case=true

The MybatisPropertyies#getConfiguration() return null when running on native-image.

reproduce project

@Mapper
public interface CityMapper {

  @Insert("INSERT INTO city (name, state, country_name) VALUES(#{name}, #{state}, #{countryName})")
  @Options(useGeneratedKeys = true, keyProperty = "id")
  void insert(City city);

  @Select("SELECT id, name, state, country_name FROM city ORDER BY id")
  Collection<City> findAll();

}
  @Bean
  ApplicationRunner runner(CityMapper mapper) {
    return args -> {
      City newCity = new City();
      newCity.setName("NYC");
      newCity.setState("NY");
      newCity.setCountryName("USA");
      mapper.insert(newCity);
      log.info("New city: {}", newCity);
      mapper.findAll().forEach(x -> log.info("{}", x)); // countryName should set non-null value, but set null
    };
  }

  @Bean
  ConfigurationCustomizer configurationCustomizer(MybatisProperties mybatisProperties) {
    return c -> {
      // Should return not null, but return null
      log.info("configuration on auto-configuration time : {}", mybatisProperties.getConfiguration());
      // Should return true, but return false
      log.info("isMapUnderscoreToCamelCase on auto-configuration time : {}", c.isMapUnderscoreToCamelCase());
    };
  }

How to reproduce

Build

./mvnw -pl mybatis-spring-native-core,mybatis-spring-native-samples/mybatis-spring-native-sample-config -Pnative clean package -U

Run with native-image(Actual Result)

./mybatis-spring-native-samples/mybatis-spring-native-sample-config/target/mybatis-spring-native-sample-config
...
★★★2022-01-08 15:51:33.647  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : configuration on configuration time : null  ★★★ Should return not null
★★★2022-01-08 15:51:33.647  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : isMapUnderscoreToCamelCase on configuration time : false  ★★★ Should return true
2022-01-08 15:51:33.655  INFO 92950 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-01-08 15:51:33.657  INFO 92950 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-01-08 15:51:33.661  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : Started MybatisSpringNativeSampleApplication in 0.034 seconds (JVM running for 0.036)
2022-01-08 15:51:33.661  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : New city: City{id=4, name='NYC', state='NY', countryName='USA'}
★★★2022-01-08 15:51:33.661  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=1, name='San Francisco', state='CA', countryName='null'}  ★★★ countryName should return not null
2022-01-08 15:51:33.661  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=2, name='Boston', state='MA', countryName='null'}
2022-01-08 15:51:33.661  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=3, name='Portland', state='OR', countryName='null'}
2022-01-08 15:51:33.661  INFO 92950 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=4, name='NYC', state='NY', countryName='null'}
...

Run with executable jar(Expected Result)

./mybatis-spring-native-samples/mybatis-spring-native-sample-config/target/mybatis-spring-native-sample-config-0.0.1-SNAPSHOT-exec.jar
...
★★★2022-01-08 15:55:36.296  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : configuration on configuration time : org.apache.ibatis.session.Configuration@6cce16f4
★★★2022-01-08 15:55:36.297  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : isMapUnderscoreToCamelCase on configuration time : true
2022-01-08 15:55:36.408  INFO 92975 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2022-01-08 15:55:36.624  INFO 92975 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2022-01-08 15:55:36.752  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : Started MybatisSpringNativeSampleApplication in 1.515 seconds (JVM running for 1.901)
2022-01-08 15:55:36.798  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : New city: City{id=4, name='NYC', state='NY', countryName='USA'}
★★★2022-01-08 15:55:36.828  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=1, name='San Francisco', state='CA', countryName='USA'}
2022-01-08 15:55:36.828  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=2, name='Boston', state='MA', countryName='USA'}
2022-01-08 15:55:36.828  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=3, name='Portland', state='OR', countryName='USA'}
2022-01-08 15:55:36.828  INFO 92975 --- [           main] s.c.MybatisSpringNativeSampleApplication : City{id=4, name='NYC', state='NY', countryName='USA'}
...

Workaround

Can use the programmatic based configuration as follows:

@SpringBootApplication
public class MybatisSpringNativeSampleApplication {
  // ...
  @Bean
  ConfigurationCustomizer mybatisConfigurationCustomizer() { // Add bean definition for ConfigurationCustomizer
    return configuration -> {
      configuration.setMapUnderscoreToCamelCase(true);
    };
  }
}

I found difference with timing of bean creation.

Running with native-image

MyBatis's components was created before create the ConfigurationPropertiesBindingPostProcessor bean.

 ./mybatis-spring-native-samples/mybatis-spring-native-sample-config/target/mybatis-spring-native-sample-config --logging.level.org.springframework.beans.factory.support=trace
...
2022-01-08 16:00:13.204 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'propertySourcesPlaceholderConfigurer'
2022-01-08 16:00:13.204 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'propertySourcesPlaceholderConfigurer'
2022-01-08 16:00:13.204 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'propertySourcesPlaceholderConfigurer'
2022-01-08 16:00:13.210 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor'
2022-01-08 16:00:13.210 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor'
2022-01-08 16:00:13.210 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'cityMapper'
2022-01-08 16:00:13.210 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'cityMapper'
2022-01-08 16:00:13.218 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'sqlSessionTemplate'
2022-01-08 16:00:13.218 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'sqlSessionTemplate'
2022-01-08 16:00:13.219 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'sqlSessionFactory'
2022-01-08 16:00:13.219 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'sqlSessionFactory'
2022-01-08 16:00:13.219 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'dataSource'
2022-01-08 16:00:13.219 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'dataSource'
2022-01-08 16:00:13.219 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:00:13.219 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:00:13.219 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Invoking afterPropertiesSet() on bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:00:13.219 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:00:13.221 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2022-01-08 16:00:13.221 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2022-01-08 16:00:13.221 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2022-01-08 16:00:13.222 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'dataSource'
2022-01-08 16:00:13.222 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:00:13.222 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:00:13.222 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:00:13.224 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:00:13.224 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:00:13.224 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'configurationCustomizer'
2022-01-08 16:00:13.224 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'configurationCustomizer'
2022-01-08 16:00:13.225 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:00:13.225 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'mybatisSpringNativeSampleApplication'
2022-01-08 16:00:13.225 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'mybatisSpringNativeSampleApplication'
2022-01-08 16:00:13.225 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'mybatisSpringNativeSampleApplication'
2022-01-08 16:00:13.226 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'configurationCustomizer'
2022-01-08 16:00:13.226 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Invoking afterPropertiesSet() on bean with name 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:00:13.226 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:00:13.227  INFO 92995 --- [           main] s.c.MybatisSpringNativeSampleApplication : configuration on configuration time : null
2022-01-08 16:00:13.228  INFO 92995 --- [           main] s.c.MybatisSpringNativeSampleApplication : isMapUnderscoreToCamelCase on configuration time : false
2022-01-08 16:00:13.229 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'sqlSessionFactory'
2022-01-08 16:00:13.229 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:00:13.229 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'sqlSessionTemplate'
2022-01-08 16:00:13.229 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Invoking afterPropertiesSet() on bean with name 'cityMapper'
2022-01-08 16:00:13.230 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'cityMapper'
2022-01-08 16:00:13.230 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'environment'
2022-01-08 16:00:13.230 TRACE 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor'
2022-01-08 16:00:13.231 DEBUG 92995 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor'
...

Running with executable jar

MyBatis's components was created after create the ConfigurationPropertiesBindingPostProcessor bean.

./mybatis-spring-native-samples/mybatis-spring-native-sample-config/target/mybatis-spring-native-sample-config-0.0.1-SNAPSHOT-exec.jar --logging.level.org.springframework.beans.factory.support=trace
...
2022-01-08 16:08:17.850 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor'
...
2022-01-08 16:08:17.853 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor'
...
2022-01-08 16:08:17.974 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'cityMapper'
2022-01-08 16:08:17.974 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'cityMapper'
2022-01-08 16:08:17.986 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'sqlSessionTemplate'
2022-01-08 16:08:17.987 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'sqlSessionTemplate'
2022-01-08 16:08:17.988 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:08:17.988 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:08:17.991 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:08:17.992 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:08:17.997 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.context.properties.BoundConfigurationProperties'
2022-01-08 16:08:17.997 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'org.springframework.boot.context.properties.BoundConfigurationProperties'
2022-01-08 16:08:17.998 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:17.998 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.springframework.boot.context.properties.BoundConfigurationProperties'
2022-01-08 16:08:18.088 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.089 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:08:18.091 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration' via constructor to bean named 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:08:18.091 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration' via constructor to bean named 'org.springframework.context.annotation.AnnotationConfigApplicationContext@55b0dcab'
2022-01-08 16:08:18.093 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'configurationCustomizer'
2022-01-08 16:08:18.093 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'configurationCustomizer'
2022-01-08 16:08:18.094 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'mybatisSpringNativeSampleApplication'
2022-01-08 16:08:18.094 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:08:18.096 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'configurationCustomizer' via factory method to bean named 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties'
2022-01-08 16:08:18.110 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.110 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'configurationCustomizer'
2022-01-08 16:08:18.111 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Invoking afterPropertiesSet() on bean with name 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:08:18.111 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.112 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:08:18.113 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'sqlSessionFactory'
2022-01-08 16:08:18.113 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'sqlSessionFactory'
2022-01-08 16:08:18.113 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration'
2022-01-08 16:08:18.114 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'dataSource'
2022-01-08 16:08:18.114 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'dataSource'
2022-01-08 16:08:18.114 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2022-01-08 16:08:18.114 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2022-01-08 16:08:18.115 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.115 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari'
2022-01-08 16:08:18.115 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:08:18.116 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating instance of bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:08:18.117 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.boot.context.properties.BoundConfigurationProperties'
2022-01-08 16:08:18.127 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Invoking afterPropertiesSet() on bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:08:18.136 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.137 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:08:18.138 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'dataSource' via factory method to bean named 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties'
2022-01-08 16:08:18.165 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.boot.context.properties.BoundConfigurationProperties'
2022-01-08 16:08:18.174 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.179 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'dataSource'
2022-01-08 16:08:18.179 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'sqlSessionFactory' via factory method to bean named 'dataSource'
2022-01-08 16:08:18.186  INFO 93042 --- [           main] s.c.MybatisSpringNativeSampleApplication : configuration on configuration time : org.apache.ibatis.session.Configuration@14fc1f0
2022-01-08 16:08:18.188  INFO 93042 --- [           main] s.c.MybatisSpringNativeSampleApplication : isMapUnderscoreToCamelCase on configuration time : true
2022-01-08 16:08:18.214 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.215 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'sqlSessionFactory'
2022-01-08 16:08:18.215 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'sqlSessionTemplate' via factory method to bean named 'sqlSessionFactory'
2022-01-08 16:08:18.225 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.227 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'sqlSessionTemplate'
2022-01-08 16:08:18.227 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Invoking afterPropertiesSet() on bean with name 'cityMapper'
2022-01-08 16:08:18.286 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.286 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'cityMapper'
2022-01-08 16:08:18.289 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.289 DEBUG 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'runner' via factory method to bean named 'cityMapper'
2022-01-08 16:08:18.291 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2022-01-08 16:08:18.291 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Finished creating instance of bean 'runner'
2022-01-08 16:08:18.291 TRACE 93042 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'configurationCustomizer'
...

@snicoll

Do you know a cause for this behavior? I would be grateful if tell me a hint for resolving this issue when you have time.

I am trying to get my head around all the details. Is this happening only in the native image or can you reproduce the problem with AOT on the JVM?

@snicoll Thanks for reaction!

This problem occurred only when run with native-image.

@snicoll I've tried joshlong's sample, it has been occurred same issue.

can you reproduce the problem with AOT on the JVM?

Sorry, tell me how to run with AOT on JVM?

Once your jar is built, java -DspringAot=true -jar yourapp.jar.

@snicoll this issue occurred running with AOT on JVM too.

@snicoll
I've debug with AOT on JVM mode. Probably directly cause is eager creating bean of MapperFactoryBean(implement FactoryBean) when creating instance of DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessor(BeanFactoryPostProcessor) bean via InstanceSupplierContext#create. As result, MyBatis and dependency components(e.g DataSource) was created before bind configuration properties.

Bean definition of MapperFactoryBean will register via generation code(ContextBootstrapInitializer) generated by AOT on build time as follows:

BeanDefinitionRegistrar.of("cityMapper", MapperFactoryBean.class)
    .instanceSupplier(() -> new MapperFactoryBean()).customize((bd) -> {
  MutablePropertyValues propertyValues = bd.getPropertyValues();
  propertyValues.addPropertyValue("mapperInterface", CityMapper.class);
  propertyValues.addPropertyValue("addToConfig", true);
  propertyValues.addPropertyValue("sqlSessionTemplate", new RuntimeBeanReference("sqlSessionTemplate"));
}).register(beanFactory);

@kazuki43zoo could you please share a minimal sample that I can run to reproduce this?

@snicoll You can reproduce this issue using mybatis-spring-native-samples/mybatis-spring-native-sample-config module on gh-13_cannot-bind-configuration-properties-to-mybatis-properties_reproduce branch, but should I make another project?

How to build:

./mvnw -pl mybatis-spring-native-core,mybatis-spring-native-samples/mybatis-spring-native-sample-config -Pnative clean package -U

Thanks. I've reproduced the problem. The injection of the Environment in DependsOnDatabaseInitializationPostProcessor triggered the resolution of factory beans and that indeed created MapperFactory too early.

It shouldn't even do that for the Environment so something isn't right. I'll continue to debug and update this issue with my findings.

So I've made some progress. It's unclear why the context behaves this way in AOT, and does not with a regular runtime but injecting the environment this way in a BFPP should be avoided. I've created spring-projects/spring-boot#29475. I've also discovered that dependsOn is not written back in the generated bean definition registration. I've created spring-attic/spring-native#1458.

Fixing the above may not fix this issues as there might be another processor that does something similar.

With the fix on the Spring Boot issue, I am getting the following:

2022-01-19 12:12:40.263  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-19 12:12:40.263  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-19 12:12:40.281  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSource' of type [com.zaxxer.hikari.HikariDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-19 12:12:40.284  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties' of type [org.mybatis.spring.boot.autoconfigure.MybatisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-19 12:12:40.289  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'mybatisSpringNativeSampleApplication' of type [org.mybatis.spring.nativex.sample.config.MybatisSpringNativeSampleApplication] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-19 12:12:40.290  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'configurationCustomizer' of type [org.mybatis.spring.nativex.sample.config.MybatisSpringNativeSampleApplication$$Lambda$426/0x00000008401e7c40] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-19 12:12:40.291  INFO 7159 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration' of type [org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

I don't get those without AOT so we're at least making progress as the issue is clearly logged by the context now.

This one is triggered by ConfigurationPropertiesBinder trying to inject an ApplicationContext. I must be missing something there.

@snicoll Thanks for your work and feedback! I will try using latest Spring Boot snapshot version!

No, thank you! You shed some light on a nasty problem. I am happy to share that I have some code that fixes the problem that I am now polishing so that it it is hopefully available in the next maintenance release. Thanks again.

Unfortunately, I spoke too soon. I thought I had fixed the issue but I haven't. Still investigating.

Edit: I think I found it, I'll try to submit a PR shortly.

I believe that #32 is one way to fix this issue. Let me know what you think.

Current status:
As result for applying spring-boot 2.6.3 and spring-native 0.11.2-SNAPSHOT latest version, we can bind configuration properties to MybatisProperties and apply to MyBatis's configuration, but some beans excluded from processing target of BeanPostProcessor.

2022-01-22 11:56:03.533  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.534  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.539  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'dataSource' of type [com.zaxxer.hikari.HikariDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.544  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties' of type [org.mybatis.spring.boot.autoconfigure.MybatisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.544  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration' of type [org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.546  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionFactory' of type [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.547  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sqlSessionTemplate' of type [org.mybatis.spring.SqlSessionTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2022-01-22 11:56:03.548  INFO 71660 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'cityMapper' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

Sample

This is the expected behavior and nothing we can do about it. MapperFactoryBean has a generic that isn't resolved so it forces the context to instantiate the factory bean early. What we need to do is make sure that the right type is exposed upfront, which is what I've tried to do in #32. Let's continue the discussion there?

fixed via #32 ! Great work for @snicoll , Thanks !!