13

データベースに対して次のクエリを実行します。

        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に関するすべての情報が表示されます。

4

4 に答える 4

37

内部のオブジェクトemployeelazy初期化されます。つまり、クローズされていないセッションでオンデマンドでのみ初期化しています。したがって、DB からフェッチした後、ループ内ですべて手動で初期化する必要があります。

Query empQuery = session.createQuery(hqlQuery);
empQuery.setMaxResults(maxResult);
employees = (List<Employee>) empQuery.list();
for (Employee emp : employees) {
    Hibernate.initialize(emp.address);
}
于 2013-01-26T22:21:46.180 に答える
16

使用できるSinche Hibernate 4.2

.setProperty("hibernate.enable_lazy_load_no_trans", "true");

このオプションは恐ろしい問題を解決します

org.hibernate.LazyInitializationException: could not initialize proxy -
no Session

これにより、プログラマーは非常に多くの時間を奪われました。

于 2016-01-21T09:26:06.967 に答える
9

マッピングとは関係ありません。オブジェクトの遅延ロードを提供する場合、ORM の世界を 10 年間魅了してきた責任を受け入れることになります。オブジェクトをロードしたセッションは、遅延リクエストが発行されたときに存在するセッションと同じになるということです。

あなたの場合、セッションが完全になくなったようです。

セッションを維持する何らかの手段が必要です (会話スコープが必要になることがよくあります。これは、Seam または CDI (EE 6 の場合) のいずれかを意味します)、またはオブジェクトを新しいセッションと再同期する必要があります (通常はもう一度調べます)。

于 2013-01-26T22:22:20.807 に答える
2

dbからオブジェクトを取得するときに、Hibernate.init(Object)に追加laze=falseするか、オブジェクトを初期化できます。<class name="com.employees.model.Employee" table="employees">

于 2013-01-26T22:36:17.723 に答える