1.1 exception1-test
1.1.1 异常信息
Method threw 'org.apache.ibatis.reflection.ReflectionException' exception. Cannot evaluate com.banma.domain.Permission_$$_jvstac4_1.toString() |
1.1.2 异常场景
1)在springmvc多表查询中,使用延迟加载;在service层测试,因为是延迟加载,如果没有写第10行代码,那么结果就不会报错,可以通过打个断点查看是否查询到数据,就会发现第二张表查询到null,并且会出现这个异常在列表中(鼠标停留在sysUser上点击出来的数据列表)
2)测试代码
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml","classpath:spring-security.xml"})
public class App2 {
@Autowired
private IUserDao userDao;
@Test
public void test2(){
SysUser sysUser = userDao.finById(1);
sysUser.getRoles().get(0).getRoleDesc();
System.out.println(sysUser);
}
}
1.1.3 异常分析过程
1)提示看出来是mybatis控制的dao层出现问题,只有两个地方,
首先还得确定配置文件没问题;第一:查询语句,第二:方法返回值
2)如果是从数据库中查询后拿过来的sql语句,那么,第一个可以排除
3)方法本身首先在调用上可以先不用考虑,如果方法本身就有问题,那检查service层调用是否出错也无用,所以在方法本身上还有两个地方:返回值类型是否弄错(这异常就是这个);返回的实体类中是否确实对应的属性以及set/get方法
4)结果在检查后发现时方法的返回List集合中实体类弄错了,因为Role类中还有另外一个实体类对象属性
@Select("select r.* from sys_user_role ur inner join sys_role r on ur.roleid=r.id where ur.userid=#{userId}")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "permissions",column = "id",javaType = List.class,
many = @Many(select = "com.banma.dao.IPermissionDao.findPermissionsByRoleId",
fetchType = FetchType.LAZY))
})
List findRolesByUserId(Integer userId);
public class Role {
private Long id;
private String roleName;
private String roleDesc;
private List permissions;
1.1.4 异常解决方案
1)修改返回值类型
List findRolesByUserId(Integer userId);
2.1 exception1-test
2.1.1 异常信息
Bean named 'orderServiceImpl' is expected to be of type 'com.banma.service.impl.OrderServiceImpl' but was actually of type 'com.sun.proxy.$Proxy71' |
2.1.2 异常场景
1)在springmvc中的实现页面方法调用时报的异常,是在使用插件实现分页效果并添加了事物支持
2)测试代码
@Controller
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderServiceImpl orderService;
/**
* 使用插件实现分页查询
* @return
*/
@RequestMapping("/findByPage")
public ModelAndView findByPage(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "2") int pageSize){
PageInfo pageInfo = orderService.findByPage(pageNum, pageSize);
ModelAndView mv = new ModelAndView();
mv.addObject("pageInfo",pageInfo);
mv.setViewName("order-list");
return mv;
}
@Service
@Transactional
public class OrderServiceImpl implements IOrderService {
@Autowired
private IOrderDao orderDao;
@Override
public List findAll() {
return orderDao.findAll();
}
/**
* 使用插件实现分页查询
*/
@Override
public PageInfo findByPage(int pageNum,int pageSize) {
//开始分页
PageHelper.startPage(pageNum,pageSize);
//调用dao查询所有
List list = orderDao.findAll();
PageInfo pageInfo = new PageInfo<>(list);
return pageInfo;
}
2.1.3 异常分析过程
1)提示看出来是实现类和产生代理对象(proxy)(AOP编程)的问题;可能出现问题的地方,第一:配置文件(事物配置(xml:管理器DataSourceTransactionManager,通知规则
2)因为是在实现分页是出现的问题,可能会第一个想到是不是插件提供的PageInfo或PageHelper使用有误,当然考虑到是AOP编程出错,这个过程使用到代理对象的只有事务管理了!所有配置文件没有问题的话,看一下service层的事物注解(@Transactional),接收service实现类的对象(Controller),这里有实现接口,所有使用的代理就是JDK代理,那么生成的代理对象只能通过接口的引用接收具体的实现(大白话就是:实现类和代理对象都是借口的实现类,要是同一级别的)
3)那就找到了问题
@Select("select r.* from sys_user_role ur inner join sys_role r on ur.roleid=r.id where ur.userid=#{userId}")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "permissions",column = "id",javaType = List.class,
many = @Many(select = "com.banma.dao.IPermissionDao.findPermissionsByRoleId",
fetchType = FetchType.LAZY))
})
List findRolesByUserId(Integer userId);
public class Role {
private Long id;
private String roleName;
private String roleDesc;
private List permissions;
2.1.4 异常解决方案
1)修改接收对象
@Autowired
private IOrderDao orderDao;