[转]hibernate错误:could not initialize proxy - no Session_se7en3_新浪博客

本文探讨了Hibernate中出现couldnotinitializeproxy-noSession异常的原因及解决办法。通过调整<many-to-one>属性lazy为false,避免了延迟加载引发的问题。

could not initialize proxy - no Session
 at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
 at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
 at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)

 

只需<many-to-one>中属性lazy设置为false即可。由于其默认为proxy

 

延迟加载, 也就是用到的时候才去加载.这样可以提高一些性能.
Hibernate的lazy loading 采用了一个HibernateSession来管理session,它的逻辑是每进行一次数据库操作,就开新的session,操作完成后立即关闭该session。这样做的好处是可以严格关闭session,避免菜鸟级的错误,但是hibernate.org并不推荐这么做。因为这不适合lazy loading,也不适合跨方法的事务。

比如在我们的应用中,user->post形成一对多的映射,User中有一个包含post的List。
在User中,有多个属性:name,password,phone等,还有一个List类型的posts。当我们对posts使用lazy laoding的时候,hibernate会在获得User对象的时候,仅仅返回name,password,phone等基本属性,当你访问posts的时候,它才会从数据库中提取posts需要的数据,这就是所谓lazy laoding。但是在我们的系统中,session是被立即关闭的,也就是在读取了name,password,phone等基本属性后,session已经close了,再进行lazy loaiding就会有异常。

 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/zhoutao198712/archive/2008/11/17/3321263.aspx

在使用 Hibernate 时,如果遇到 `could not initialize proxy - no Session` 错误,通常意味着尝试访问延迟加载(Lazy Loading)的关联对象时,当前的 Session 已经关闭或不可用。以下是常见的原因及解决方案: ### 1. Session 生命周期管理不当 Hibernate 的延迟加载依赖于 Session 的存在。如果在获取实体对象后关闭了 Session,再访问其延迟加载的关联属性时就会抛出此异常。解决办法是在访问关联对象之前保持 Session 的打开状态。 ```java Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); // 获取实体对象 User user = session.get(User.class, 1L); // 在 Session 未关闭前访问延迟加载的属性 System.out.println(user.getOrders().size()); tx.commit(); session.close(); ``` ### 2. 使用 Open Session in View 模式 在 Web 应用中,特别是在 MVC 架构中,有时在 Controller 层获取了实体对象,但在 View 层才真正访问其关联属性。此时 Session 可能已经被关闭。为了解决这个问题,可以使用 Open Session in View 模式,确保在整个请求生命周期中 Session 保持打开状态。 在 Spring Boot 中可以通过配置启用该模式: ```yaml spring: jpa: open-in-view: true ``` ### 3. 显式初始化代理对象 可以使用 `Hibernate.initialize()` 方法显式初始化代理对象,确保在 Session 有效期内完成加载。 ```java User user = session.get(User.class, 1L); Hibernate.initialize(user.getOrders()); // 显式初始化 session.close(); // 此时即使 Session 已关闭,也可以安全访问 orders System.out.println(user.getOrders().size()); ``` ### 4. 改变 FetchType 为 EAGER 如果某个关联属性频繁被访问,可以考虑将其 `fetch` 类型改为 `EAGER`,避免延迟加载带来的问题。 ```java @OneToMany(fetch = FetchType.EAGER) private Set<Order> orders; ``` ### 5. 使用 JOIN FETCH 优化查询 在 HQL 或 Criteria 查询中使用 `JOIN FETCH` 显式加载关联对象,避免延迟加载。 ```java String hql = "FROM User u JOIN FETCH u.orders WHERE u.id = :id"; User user = session.createQuery(hql, User.class) .setParameter("id", 1L) .uniqueResult(); ``` ### 6. 确保事务边界合理 确保在事务边界内完成所有必要的数据访问操作,避免在事务提交或回滚后访问延迟加载的属性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值