Mybatis Spring integration, project start-up times wrong: (MapperScannerConfigurer sqlSessionFactoryBeanName injection pattern)

pringframework.beans.factory.BeanCreationException: Error creating bean with name 'mapperScannerConfigurer'defined in class path resource [applicationContext.xml]: 
Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sqlSessionFactory';
 nested exception is org.springframework.beans.factory BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: 
Cannot resolve reference to bean 
'dataSource' while setting bean property 'dataSource';
 nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [applicationContext.xml]: Error setting property values;
nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception;
 nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [${driver}]
Copy the code

As you can see, there are five errors, large and small:

Pringframework. Beans. Factory. BeanCreationException: create a “mapperScannerConfigurer” an error occurred when the bean, This bean is defined in the classpath resource [ApplicationContext.xml] : Reference to bean “sessionFactory” cannot be resolved when setting the bean property “sqlSessionFactory”;

Nested exception is org. Springframework. Beans. Factory BeanCreationException: create a “sessionFactory” an error occurred when the bean, The bean is defined in the classpath resource [applicationContext.xml] : the reference to the bean cannot be resolved. Nested exception is org. Springframework. Beans. Factory. BeanCreationException: create a “dataSource” an error occurred when the bean, The bean is defined in the classpath resource [ApplicationContext.xml] : an error occurred while setting the property value; Nested exception is org. Springframework. Beans. PropertyBatchUpdateException; The nested PropertyAccessException (1) is: 1: PropertyAccessException org. Springframework. Beans. MethodInvocationException: Property ‘driverClassName throw an exception; Nested exception for Java. Lang. An IllegalStateException: unable to load the JDBC driver class ${the driver} []

Ok, so here is the source code for my Spring configuration file

<context:property-placeholder location="classpath:/jdbc.properties"/>
<! Configure the data source bean.
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="password" value="${password}"/>
        <property name="username" value="${user}"/>
    </bean>
    <! -- SqlSessionFactory bean -->
    <bean name="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <! -- Scan Mapper files -->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactory" ref="sessionFactory"/>
        <property name="basePackage" value="com.lyl.mapper"/>
    </bean>
Copy the code

By analyzing the error information provided by the log, it was found that the program did not load the JDBC driver, that is, the driverClassName of the data source bean was not loaded successfully, because I used jDBC.properties to load the data source parameter information. ${driver} = ${driver} = ${driver} = ${driver} = ${driver} = ${driver} SqlSessionFactorybean = sqlSessionFactorybean = sqlSessionFactorybean = sqlSessionFactorybean = sqlSessionFactorybean SqlSessionFactory also can’t go wrong, so I will by mapperScannerConfigurerbean sights, there is nothing wrong with because he injected SQL Session Factory, and then began to baidu, and sure enough, You get the wrong answer and you get it. The original mapperScannerConfigurerbean:

<! -- Scan Mapper files -->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactory" ref="sessionFactory"/>
        <property name="basePackage" value="com.lyl.mapper"/>
    </bean>
Copy the code

The modified mapperScannerConfigurerbean:

  <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
<! -- <property name="sqlSessionFactory" ref="sessionFactory"/>-->
        <property name="basePackage" value="com.lyl.mapper"/>
    </bean>
Copy the code

Can be found, no longer injection sqlSessionFactory properties, instead sqlSessionFactoryBeanName properties, and USES the value to assign a value, program can run normally. So the problem is solved. What’s the mechanism? I have baidu sqlSessionFactoryBeanName this attribute.

There are four injection modes in MapperScannerConfigurer. The injection mode of sqlSessionFactory is outdated. The root cause of this error is Found in MapperScannerConfigurer.

Before mybatis 1.1.0, the SqlSessionFactory object was injected into the SqlSessionFactory. There was a problem with this. When mybatis was initialized, the jdbc.properties file was not loaded. DataSource class sqlSessionFactory is not replaced, the dataSource fails to load. After the 1.1.0 MapperScannerConfigure sqlSessionFactoryBeanName provides a type String, it will bean name into sqlSessionFactoryBeanName, This will wait until Spring initialization is complete before building the sqlSessionFactory.

Finally found the nature of the mistake, toss and toss for most of the day! Properties file conflicts with SqlSessionFactory. Add SqlSessionFactory to MapperScannerConfigurer. If you use placeholders to configure the dataSourcebean, you might cause the sqlSessionFactory build to precede the loading of the jdbc.properties file.

There is currently no solution to using sqlSessionFactory for successful injection (unless you write JDBC values directly without using placeholders), but that is outdated.