spring-boot-starter icon indicating copy to clipboard operation
spring-boot-starter copied to clipboard

Incompatible type between Configuration SqlSessionFactoryBean and MybatisProperties

Open szopal opened this issue 10 months ago • 4 comments

After upgrade mybatis version to 3.0.3 I can't customize SqlSessionFactory because I can't set mybatis properties configuration like I did in 2.3.1

@Bean
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
public SqlSessionFactory sqlSessionFactoryBean(final MybatisProperties properties) throws Exception {
  final SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
  [...here is some of my code...]
  factoryBean.setConfiguration(properties.getConfiguration());
  return factoryBean.getObject();
}

There is error:

image

szopal avatar Apr 15 '24 11:04 szopal

Hello @szopal ,

I moved the issue to mybais-spring-boot-starter repo.

See if ConfigurationCustomizer or SqlSessionFactoryBeanCustomizer helps.

There also seems to be a case that is not covered currently. See #928 .

If none of the above helps, please elaborate on the usage details.

harawata avatar Apr 15 '24 16:04 harawata

I'm not sure if you understand me - In previous version (2.x) I customize SqlSessionFactory like this:

@Bean
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
public SqlSessionFactory sqlSessionFactoryBean(final MybatisProperties properties) throws Exception {
  final SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
  factoryBean.setDataSource(dataSource);
  factoryBean.setMapperLocations();
  Resource[] mappers;
  final Resource[] resource1 = new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mappers/*.xml");
  try {
    final Resource[] resource2 = new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/batch/mappers/*.xml");
    mappers = ArrayUtils.addAll(resource1, resource2);
  } catch (final FileNotFoundException fnfe) {
    mappers = resource1;
  }
  factoryBean.setMapperLocations(mappers);
  factoryBean.setTypeAliasesPackage("app.core.repository.enumhandler"); =
  factoryBean.setTypeHandlersPackage("app.repository.typehandler");
  factoryBean.setConfiguration(properties.getConfiguration());
  return factoryBean.getObject();
}

The main part of code is:

factoryBean.setConfiguration(properties.getConfiguration());

But now, I have to do like this:

  @Bean
  @ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
  public SqlSessionFactory sqlSessionFactoryBean(final MybatisProperties properties) throws Exception {
    final SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(dataSource);
    factoryBean.setMapperLocations();
    Resource[] mappers;
    final Resource[] resource1 = new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mappers/*.xml");
    try {
      final Resource[] resource2 = new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/batch/mappers/*.xml");
      mappers = ArrayUtils.addAll(resource1, resource2);
    } catch (final FileNotFoundException fnfe) {
      mappers = resource1;
    }
    factoryBean.setMapperLocations(mappers);
    factoryBean.setTypeAliasesPackage("app.core.repository.enumhandler");
    factoryBean.setTypeHandlersPackage("app.repository.typehandler");
    if (properties.getConfiguration() != null) {
      // @formatter:off
      final Configuration configuration = new Configuration();
      configuration.setCacheEnabled(Optional.ofNullable(properties.getConfiguration().getCacheEnabled()).orElse(Boolean.FALSE));
      configuration.setDefaultFetchSize(properties.getConfiguration().getDefaultFetchSize());
      configuration.setDefaultEnumTypeHandler(properties.getConfiguration().getDefaultEnumTypeHandler());
      configuration.setDefaultExecutorType(properties.getConfiguration().getDefaultExecutorType());
      configuration.setJdbcTypeForNull(properties.getConfiguration().getJdbcTypeForNull());
      configuration.setMapUnderscoreToCamelCase(Optional.ofNullable(properties.getConfiguration().getMapUnderscoreToCamelCase()).orElse(Boolean.FALSE));
      configuration.setReturnInstanceForEmptyRow(Optional.ofNullable(properties.getConfiguration().getReturnInstanceForEmptyRow()).orElse(Boolean.FALSE));
      configuration.setUseColumnLabel(Optional.ofNullable(properties.getConfiguration().getUseColumnLabel()).orElse(Boolean.FALSE));
      configuration.setUseGeneratedKeys(Optional.ofNullable(properties.getConfiguration().getUseGeneratedKeys()).orElse(Boolean.FALSE));
      // @formatter:on

      factoryBean.setConfiguration(configuration);
    }
    return factoryBean.getObject();
  }

Because configuration from MybatisProperties is different type and it can't be rewrite automatically. But, maybe I do something wrong - If yes, please let me know.

szopal avatar Apr 17 '24 13:04 szopal

This changed in 3.0. There's a more concise way to write your code:

if (properties.getConfiguration() != null) {
    final Configuration configuration = new Configuration();
    properties.getConfiguration().applyTo(configuration);
    factoryBean.setConfiguration(configuration);
}

jeffgbutler avatar Apr 17 '24 14:04 jeffgbutler

Thank very much! Now I can see it's changed in 3.0.

szopal avatar Apr 18 '24 07:04 szopal

closing issue as seems resolved.

hazendaz avatar Jul 15 '24 00:07 hazendaz