文章字数: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
注解可以使代码块事务统一。