Java各种框架还是比较 复杂的,如果不去看官方的文档或者不踩坑
都不会知道原来框架在运行的过程中还会偷偷的做一些其他的事情
踩坑
假设现在有一个Entity为Person,使用JPA存到数据库中,会调用Hibernate。代码中使用personDao.findById()
来从数据库中获取一个Person实例。代码中大概就是这么写的
那么,如果我们现在要使用Redis,存入的时候需要将这个Person的实例序列化,取出的时候需要反序列化。序列化的时候没有出现什么问题, 但是反序列化的时候就出现了报错,原因是说取出的这个实例不是一个Person
,而是一个$HibernateProxy$PeGtBDW9
为什么代码里面明明写的是Person person = personDao.findById(123)
,为什么出来的实例类型不是Person
而是Person
后面加了一串的东西
解惑
经过搜索,使用HIbernate使用Proxy实现延迟加载功能。
Hibernate将对象换成代理Proxy之后,可能还会有其他的坑;比如直接访问成员变量可能访问不到,逾期行为和实际行为不一致、instanceOf的行为可能与预期的不一致等等
解决
第一个方法,如果不确定它是否是Proxy,可以强行让Hibernate给我们转换为真正的实例。Object unproxiedEntity = Hibernate.unproxy(proxy); // 自己再做强制类型转换
第二个方法,通过注解,不让Hibernate给这个Entity / Model 做延迟加载@Proxy(lazy = false)