Hibernate延迟加载,Session关闭与Set,Map的关联设计
延迟加载:在Hibernate里面,为了避免关联关系带来无谓的性能开销。
延迟加载导致的问题,一方面存在session关闭了,另一方面,试图通过Session获取实际的数据,则报出异常:Failed to lazily initialize a collection - no session or session is closed
这样场景是存在的。
解决方案如下:
Hibernate.initialize(user.getAddress());
session.close();
Set set = user.getAddresses();
为了实现透明化延迟加载机制,hibernate进行了大量努力,其中包括JDK中的Collection接口的独立实现。
如果你尝试:
Set set = (java.util.HashSet)user.getAddresses();
注:Hibernate对Conllection自身的实现:net.sf.hibernate.collection.Set。
其实会报ClassCaseException异常。因为Hibernate是对Collection接口的独立实现,而非本事JDK中的Collection接口下实现类(HashSet,HashMap)。
这也是为什么我们必须编写POJO对象涉及Set,Map而非特定JDK的Collection接口下实现类(HashSet,HashMap)。
Hibernate由于Collection自身的实现,从容完成了从Collection这层的延迟加载特性。只有程序真正访问或者读取这个Collection时,才激发Hibernate封装的底层数据库操作。(我们可以想象,,其实也是这种应该可以通过观察者模式来通知封装的底层JDBC组件,反射机制也肯定用到了,不然怎么判断Collection这种属性和geter/setter这种行为)