• 禁用 Hibernate 的代理(proxy),获取其真实对象 / Disable Hibernate Proxy and Retrieve Real Entity Object

    Java 的各种框架还是很复杂的,不看文档或者不踩坑,都不知道原来框架还“偷偷地”做了一些别的事情——可能这就是一部分面试题的出处吧😂

    踩坑

    假设有一个 Model 叫做 Person,存到数据库里,框架用的是 Hibernate。代码中用 personDao.findById() 来从数据库中获取一个 Person 实例。项目中大概就是这么写的。

    问题来了:要把这个 Person 实例序列化,之后再反序列化。序列化的时候没发现什么问题,反序列化的时候报错了,告诉我这不是一个 Person,而是一个 Person$HibernateProxy$9cjcxRNr

    啥情况,代码明明写的是 Person person = personDao.findById(123); 怎么出来的不是 Person 而是 Person 后面加了一长串东西?

    解惑

    经过搜索,得知 Hibernate 使用 Proxy 实现延迟加载(Lazy Loading)功能。延迟加载,这个我懂,真正用到时才去查询。

    找到的资料还告诉我,被偷偷换成了 proxy 之后,还可能有别的坑:直接访问成员变量可能访问不到、用 IDE 断点调试时的行为和实际运行的行为不一致、instanceOf 的行为可能与预期不一致等。

    解决

    第一个办法,若不确定它是不是 proxy,可以强行让 Hibernate 给我们转回真正的实例,是就转,不是就原样返回:

    Object unproxiedEntity = Hibernate.unproxy(proxy); // 自己再做强制类型转换

    第二个办法,通过注解,不让 Hibernate 给这个 Model / Entity Class 做延迟加载:

    @Proxy(lazy = false)

    相关参考

  • phpMyAdmin 的轻量化替代:Adminer

    平时不怎么管理 SQL 数据库,一般就只知道 phpMyAdmin,服务商一般也只提供 phpMyAdmin。

    现在在自己维护的服务器中安装一个 phpMyAdmin,真是吓到我了:.zip 下载下来有十几MB,解压完有 3000+ 个文件。然后我还不会配置,上网查教程搞了十分钟才连上。

    后来找到了 Adminer,只有一个文件,传上去 1 分钟就能连上数据库。真是太适合只用来看一下数据库、稍微改点东西的用户了。推荐。