问题
处理一对多问题时遇到
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.hibernate.entity.User.addresses, could not initialize proxy - no Session
原因
hibernate 时默认 init=“prox”
https://blog.csdn.net/qq_40437152/article/details/81461151
解决
解决一
把“一对多”中的一的映射文件中的lazy设置为false
<list name="addresses" cascade="all" lazy="false">
<key column="user_id"/> <!-- 告诉系统用外键表Address中的外键字段user_id字段来查找 -->
<index column="address_index"/>
<one-to-many class="Address"/> <!-- 告诉系统查找到后转换为Address -->
</list>
这是一劳永逸的办法,但并不是最好的解决办法
直接设置为false,违背了延迟加载的初衷
最好的方法应该是:
解决二
在配置文件中设置为true
<list name="addresses" cascade="all" lazy="true">
<key column="user_id"/> <!-- 告诉系统用外键表Address中的外键字段user_id字段来查找 -->
<index column="address_index"/>
<one-to-many class="Address"/> <!-- 告诉系统查找到后转换为Address -->
</list>
使用session.load进行加载,因为session.get()是没有延迟加载功效的;
/**
* 查询
* @param id
* @return
*/
public User findUserById(int id ) {
Session session = HibernateUtil.getSession();
// User u = session.get(User.class, id);//查询出来的数据封装成user,关闭延迟加载:在加载单个实体时,可以使用get()方法。
User u = session.load(User.class, id); //打开延迟加载,先加载到缓存中,返回的是代理对象,
System.out.println(u.getAddresses().get(0).toString());
//等到真正需要使用该对象的数据时才创建这个真正的对象,真正从数据库中加载它的数据,比如现象,而且得在session关闭前访问这些懒加载对象(代理对象),
session.close();
return u;
}