java.lang.StackOverflowError
但配置mybatis-spring时报java.lang.StackOverflowError
环境:
配置时使用的是MapperScannerConfigurer
(注:用此方式会自动创建basePackage配置中指定的包下的接口的实现类,在容器中隐式生成id为接口名小写的bean)
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zx.mapper"/>
</bean>
mapper接口:
public interface UserMapper {
//查询所有用户
@Select("select * from User")
List<User> selectUser();
//添加用户
int addUser(User user);
//删除用户
int deleteUser(int id);
}
配置事务 aop织入
事务管理器配置情况:
<!--配置声明式事务 方式二-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--结合aop实现事务的织入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<!--配置事务的传播特性:propagation=-->
<tx:attributes>
<!-- <tx:method name="addUser" propagation="REQUIRED"/>-->
<!-- <tx:method name="deleteUser" propagation="REQUIRED"/>-->
<!-- <tx:method name="update" propagation="REQUIRED"/>-->
<!-- <tx:method name="selectUser" propagation="REQUIRED" read-only="true"/>-->
<!--此条等同于上面四条-->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<!--切入点:com.zx.mapper包下的所有类的所有方法(任意参数)-->
<aop:pointcut id="txPointCut" expression="execution(* com.zx.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
然后我写了一个实现类来测试事务回滚
public class UserMapperImpl implements UserMapper{
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public List<User> selectUser() {
System.out.println("-----why-----");
//添加用户
User user = new User();
user.setId(6);
user.setName("地动仪");
user.setPwd("666");
addUser(user);
//删除用户(故意将sql语句写错,看是否回滚)
deleteUser(6);
return userMapper.selectUser();
}
@Override
public int addUser(User user) {
return userMapper.addUser(user);
}
@Override
public int deleteUser(int id) {
return userMapper.deleteUser(id);
}
}
实现类的bean(注意异常就是这里)
<!--userMapper的实现类-->
<bean id="userMapper" class="com.zx.mapper.UserMapperImpl">
<property name="userMapper" ref="userMapper"/>
</bean>
</beans>
测试方法:
//测试事务
@Test
public void TestTransaction(){
ApplicationContext context=new ClassPathXmlApplicationContext("spring-mybatis.xml");
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
解决方法很简单,就是将这个实现类的id更改一下防止和隐式的userMapper重名。
难点就是要理解mapperScannerConfigurer会自动代理生成同名的接口实现类
注意:如果通过类型来获取bean的话会报org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.zx.mapper.UserMapperImpl' available
原因同上:已经存在两个同名的实现类了所以只能改id值