0

I'm facing a problem with Spring: I'm migrating from Spring Security ver. 3.2.7.RELEASE to 4.0.2.RELEASE. Everything was working fine in older version, however a problem occured when it came to loading DataSource.

Let me describe the architecture:

Application is secured with both SAML and LDAP mechanisms (SAML configuration is pretty similar to config given here: https://github.com/vdenotaris/spring-boot-security-saml-sample/blob/master/src/main/java/com/vdenotaris/spring/boot/security/saml/web/config/WebSecurityConfig.java).

They both need to connect to database in order to get some required data. We use MyBatis with Spring Mybatis to get needed data. That's, where the problem begins.

My DAO configuration class looks like this:

@Configuration
@EnableConfigurationProperties
@MapperScan(basePackages = { "pl.myapp" })
public class DaoConfiguration {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }

    @Bean
    @Primary
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        // some stuff happens here
        return sqlSessionFactoryBean;
    }

    @Bean
    @Primary
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    @ConfigurationProperties(prefix = "liquibase.datasource")
    @ConditionalOnProperty(name="liquibase.enabled")
    public DataSource liquibaseDataSource() {
        DataSource liquiDataSource = DataSourceBuilder.create().build();
        return liquiDataSource;
    }
}

In previous version it worked like a charm, but now it has a problem loading mappers, resulting in Bean creation exception on FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someMapper' defined in file [<filename>]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

over and over again (it's not my problem, it's a known Spring/MyBatis bug).

I did some debugging and discovered something interesting: it looks like DaoConfiguration is not treated like a configuration here! I mean: if I add

@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
    return sqlSessionFactoryBean().getObject();
}

to this config, "normal" call of @Bean annotated method should result in calling proper interceptor, here it lacks this funcionality.

My prediction is that: this config class has not been properly wrapped yet and Spring Security already needs beans produced by it.

Is there any solution to properly load this configuration before Spring Security is initialized? Or am I just wrong and missing something (maybe not so) obvious?

  • I would remove all the datasource and transaction stuff, as that is already done by Spring Boot and simply inject the `DataSource`. How are you loading the mappers are those defined as beans if so you could add the `@DependsOn` annotation to those beans. – M. Deinum Sep 08 '15 at 06:20
  • Unfortunately, we use multiple `DataSource`s with different properties, so we need to have them annotated with `@ConfigurationProperty` (great annotation btw). I tried to create another class with `@MapperScan` and `@Import` annotations where I moved `sqlSessionFactoryBean` method, but I am not sure, if I tried using `@DependsOn` properly. Thanks for reply, I'll try this annotation! – Jan Wojciechowski Sep 08 '15 at 06:55
  • I get that you have multiple datasources but that doesn't mean you have to reconfigure the defaults... You can simply add your own, the default is also the primary (if I'm not mistaken). It would save you some code/configuration :). – M. Deinum Sep 08 '15 at 06:58
  • Sadly, this did not solve the case. Funny thing is: when I added `sqlSessionFactory` method, Spring recognised this method as bean producer (so it realised `@Bean` annotation) and called it to produce this bean, but when this method calls another `@Bean` annotated method, it calls it like a regular POJO method, not wrapped by Spring. On the other hand, Liquibase and it's `DataSource` are initialized nicely. I'm lost here... – Jan Wojciechowski Sep 08 '15 at 12:59

0 Answers0