Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible type between Configuration SqlSessionFactoryBean and MybatisProperties #959

Open
szopal opened this issue Apr 15, 2024 · 4 comments

Comments

@szopal
Copy link

szopal commented Apr 15, 2024

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

@harawata harawata transferred this issue from mybatis/mybatis-3 Apr 15, 2024
@harawata
Copy link
Member

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.

@szopal
Copy link
Author

szopal commented Apr 17, 2024

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.

@jeffgbutler
Copy link
Member

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

@szopal
Copy link
Author

szopal commented Apr 18, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants