休眠:org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话 [重复]
Posted
技术标签:
【中文标题】休眠:org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话 [重复]【英文标题】:Hibernate: org.hibernate.LazyInitializationException: could not initialize proxy - no Session [duplicate] 【发布时间】:2013-01-10 14:48:42 【问题描述】:对数据库进行以下查询:
Session session = EmployeesDAO.getSessionFactory().getCurrentSession();
List<Employee> employees = new ArrayList<Employee>();
try
session.beginTransaction();
String hqlQuery = "from Employee emp "
+ "left join fetch emp.employeesOffices employeesOffice "
+ "left join fetch employeesOffice.office employeesOfficeOffice "
+ "left join fetch employeesOfficeOffice.company "
+ "left join fetch emp.address empAddress "
+ "left join fetch empAddress.city empAddressCity "
+ "left join fetch empAddressCity.country";
Query empQuery = session.createQuery(hqlQuery);
empQuery.setMaxResults(maxResult);
employees = (List<Employee>) empQuery.list();
session.getTransaction().commit();
catch (HibernateException e)
session.getTransaction().rollback();
e.printStackTrace();
在获取employee.address.street、employee.address.houseNumber 或employee.address.city 时失败并出现以下异常:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at com.employees.model.Address_$$_javassist_6.getCity(Address_$$_javassist_6.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:87)
at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:67)
at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:985)
at org.apache.jsp.WEB_002dINF.listEmployees_jsp._jspx_meth_c_005fout_005f3(listEmployees_jsp.java:306)
at org.apache.jsp.WEB_002dINF.listEmployees_jsp._jspx_meth_c_005fforEach_005f1(listEmployees_jsp.java:248)
at org.apache.jsp.WEB_002dINF.listEmployees_jsp._jspx_meth_c_005fforEach_005f0(listEmployees_jsp.java:155)
at org.apache.jsp.WEB_002dINF.listEmployees_jsp._jspService(listEmployees_jsp.java:89)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:690)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:477)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at com.employees.controller.EmployeeController.processRequest(EmployeeController.java:69)
at com.employees.controller.EmployeeController.doGet(EmployeeController.java:30)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
为员工映射:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.employees.model.Employee" table="employees">
<id column="employee_id" name="employeeId" type="int">
<generator class="sequence">
<param name="sequence">EMP_SEQ</param>
</generator>
</id>
<property column="first_name" name="firstName" type="java.lang.String" />
<property column="last_name" name="lastName" type="java.lang.String" />
<many-to-one name="address" column="address_id"
class="com.employees.model.Address"/>
<set name="employeesOffices" >
<key column="employee_id" />
<one-to-many class="com.employees.model.EmployeeOffice"/>
</set>
</class>
</hibernate-mapping>
地址映射:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.employees.model.Address" table="addresses">
<id column="address_id" name="addressId" type="int">
<generator class="sequence">
<param name="sequence">ADDRESS_SEQ</param>
</generator>
</id>
<property column="street" name="street" type="java.lang.String" />
<property column="house_number" name="houseNumber" type="int" />
<many-to-one name="city" column="city_id"
class="com.employees.model.City"/>
</class>
</hibernate-mapping>
其他类(Office、Company 等)完全正常。如果注释在 jsp 应用程序中加载地址字段的行没有任何异常。怎么了?顺便说一句,尽管有异常,它会显示有关 jsp 的所有信息。
【问题讨论】:
题外话:我觉得最好在hibernate-mapping标签中指定包属性,之后就不用写类的全名了 【参考方案1】:employee
中的对象被 lazy
初始化。这意味着,他们仅在非封闭会话上按需初始化。所以你必须在从数据库中获取后在循环内手动初始化它们:
Query empQuery = session.createQuery(hqlQuery);
empQuery.setMaxResults(maxResult);
employees = (List<Employee>) empQuery.list();
for (Employee emp : employees)
Hibernate.initialize(emp.address);
【讨论】:
那懒惰有什么意义呢?不妨更改语义以进行急切的获取。 @Rob 这并不总是需要的。有时延迟初始化很方便,只在需要时才初始化子节点。 是的,这就是为什么我的建议是您为每种情况都获得正确的范围语义。 :) 为什么他们lazy
被初始化了?为什么Office
和其他关联可以正常工作? left join fetch
提供 eager
获取是不是错了?
这里的重点是你希望映射默认是惰性的。这使您有机会在知道需要时加载数据,但如果不需要,则不会。如果您需要数据,您就需要数据,您无法摆脱它!您可以在关闭会话之前使用连接提取或仅访问该属性,但无论哪种方式,您都需要该数据,因此请确保加载它!【参考方案2】:
Sinche Hibernate 4.2 你可以用
.setProperty("hibernate.enable_lazy_load_no_trans", "true");
这个选项解决了可怕的问题
org.hibernate.LazyInitializationException: could not initialize proxy -
no Session
这花费了程序员这么多小时的生命。
【讨论】:
在 Hibernate 4.3.11.Final 中对我不起作用 这在 Hibernate 5.0.11.Final 上成功了 为我工作 - Hibernate 4.3.6 Final 在执行此操作之前,您可以read this article。 这是反模式【参考方案3】:与映射无关。当您为对象提供延迟加载时,您接受了一个使 ORM 世界迷惑了十年的责任:您加载对象的会话将与当前会话相同何时发出惰性请求。
在您的情况下,会话似乎完全消失了。
您必须有一些方法来维护会话(这通常会导致需要会话范围,这意味着 Seam 或 CDI(在 EE 6 中))或者您必须将对象与新会话重新同步你有(通常通过再次查找)。
【讨论】:
【参考方案4】:将laze=false
添加到<class name="com.employees.model.Employee" table="employees">
或者当您从 db 获取对象时,您可以在 Hibernate.init(Object) 中初始化您的对象
【讨论】:
谢谢,但lazy=false
无济于事。我在另一个答案下回答了Hibernate.initialize
。它也不起作用。
哦。我犯了错误。在 以上是关于休眠:org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话 [重复]的主要内容,如果未能解决你的问题,请参考以下文章