文章字数:564,阅读全文大约需要2分钟
记一次查找问题的过程
做一个用
jpa从数据库中查找数据,修改再保存到数据库的简单功能。查找出来后使用
BeanUtil将修改的信息放入jpa的对象中,结果报了错误Could not copy property 'id' from source to target查看
BeanUtil的源代码
1 | if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) { |
发现在反射调用失败后统一返回这个异常,于是打断点。果然是反射报的异常。
检查属性是否一一对应,是否有公共的
get和set,是否有基础类型(有的话传入空会空指针)都没发现有问题,于是手动赋值又运行了一遍。
1 | a.setId(b.getId()); |
期初只是为了测试一下方法是否被私有化,属性名是否一致。结果抛出异常
LazyInitializationException这才是导致反射出错的原因,异常信息的意思大致是
session被关闭。在stackoverflow上找到解决方法:方法上加上@Transactional。最后成功解决问题,回想了一下。当元素或者元素的lazy属性为true时执行
find()得到的只是一个代理对象,只有执行getId()时才会从数据库中取。然后取的时候事务已经关闭了。(可能是因为find操作是在Stream流中进行的,流关闭事务也关闭了)加上@Transactional注解可以使代码块事务统一。