2011-04-18 18 views
1

JPAのHibernateとSpring MVCを使用しています。私は実装されたリポジトリパターンを持っていた。 私はPageRepositoryを取得するだけで、dbからPageオブジェクトを取得します。コントローラで、私はpageObject.getWidgets()(怠惰な定義)にアクセスしようとしていますが、セッションが閉じられているという例外が出ます。Spring MVC JPA遅延例外

ただ、明確にするためには、ここでは、コントローラのコードである

@RequestMapping(value = "/pages/get",method=RequestMethod.GET) 
    public @ResponseBody String getPage(@RequestParam Long id){ 
     ..... 
      Page page = pageRepository.getById(id); 
      if(page!=null && page.getWidgets()!=null){ 
       for(Widget widget: page.getWidgets()){ <--- here the exception occurs 
        .... } 

リポジトリ

@PersistenceContext 
    public void setEntityManager(EntityManager em) { 
     this.em = em; 
    } 

    protected abstract Class<T> getConcreteClass(); 

    @Override 
    public T getById(long id) { 
     return em.find(getConcreteClass(), id); 
    } 

ウィジェット

@OneToMany(fetch=FetchType.LAZY,orphanRemoval=true,cascade=CascadeType.ALL,mappedBy="page") 
    public List<Widget> getWidgets() { 
     return widgets; 
    } 

    public void setWidgets(List<Widget> widgets) { 
     this.widgets = widgets; 
    } 

私のウェブとの関係でモデルの簡単なコード.xml

<?xml version="1.0" encoding="UTF-8"?> 
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 
     <display-name>Spring3MVC</display-name> 
     <welcome-file-list> 
     <welcome-file>index.jsp</welcome-file> 
     </welcome-file-list> 
     <filter> 
     <filter-name>sitemesh</filter-name> 
     <filter-class> 
      com.opensymphony.module.sitemesh.filter.PageFilter 
     </filter-class> 
     </filter> 
    <filter-mapping> 
     <filter-name>sitemesh</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 



     <servlet> 
     <servlet-name>spring</servlet-name> 
     <servlet-class> 
       org.springframework.web.servlet.DispatcherServlet 
      </servlet-class> 
     <load-on-startup>1</load-on-startup> 
     </servlet> 
     <servlet-mapping> 
     <servlet-name>spring</servlet-name> 
     <url-pattern>*.html</url-pattern> 
     </servlet-mapping> 
     <servlet> 
     <servlet-name>Resource Servlet</servlet-name> 
     <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class> 
     </servlet> 
     <servlet-mapping> 
     <servlet-name>Resource Servlet</servlet-name> 
     <url-pattern>/resources/*</url-pattern> 
     </servlet-mapping> 
     <!-- 
     Spring Security 
     --> 

     <context-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value> 
       ... 
      </param-value> 
     </context-param> 

     <filter> 
      <filter-name>springSecurityFilterChain</filter-name> 
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
     </filter> 

     <filter-mapping> 
      <filter-name>springSecurityFilterChain</filter-name> 
      <url-pattern>/*</url-pattern> 
     </filter-mapping> 
     <!-- 
     Spring Security 
     --> 

     <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
     </listener> 


    </web-app> 

私の春、サーブレット

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 


    .... 
    <bean id="localeResolver" 
     class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> 
     <property name="defaultLocale" value="es"/> 
    </bean> 

    <bean id="handlerMapping" 
     class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
     <property name="interceptors"> 
      <ref bean="localeChangeInterceptor" /> 
     </property> 
    </bean> 


    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    ... 
    </bean> 

    <bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    p:dataSource-ref="dataSource" 
    p:jpaVendorAdapter-ref="jpaAdapter"> 
     <property name="loadTimeWeaver"> 
       <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/> 
     </property>        
     <property name="persistenceUnitName" value="sparkPersistenceUnit"></property> 
    </bean> 

    <bean id="jpaAdapter" 
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" 
    p:database="MYSQL" 
    p:showSql="true" 
    p:generateDdl="true"/> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
    p:entityManagerFactory-ref="entityManagerFactory"/> 

    <tx:annotation-driven transaction-manager="transactionManager"/> 



</beans> 

例外

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.model.Page.widgets, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383) 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375) 
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368) 
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111) 
    at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272) 
    at com.sprekelia.spark.controller.PageController.getPage(PageController.java:78) 
    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 org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710) 
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167) 
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414) 
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552) 
    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:306) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:312) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:95) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:119) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:91) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:324) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:165) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129) 
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:77) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:558) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:281) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 

さて、私はこの問題を解決するために何ができるのでしょうか?事前

答えて

4

おかげでは、Hibernateを経由して、純粋なJPAが、JPAを使用していないと、あなたの方法に@Transactionalのアノテーションを追加する必要が動作するように遅延ロードを取得します。これにより、メソッドの存続期間中に接続が開いたままになります。

コントローラメソッドは外部から呼び出されることはないため、@Transactionalが依存するプロキシ処理の対象にはなりません。エンティティグラフのトラバーサルコードを「サービス」クラスに移動してそこに@Transactionalを適用する必要があります。

+0

CGLIB2が利用できないため、次の例外が発生します。プロキシターゲットクラスではありません。 CGLIBをクラスパスに追加するか、プロキシインタフェースを指定します。 –

+0

あなたはそれを必要とします。 – splonk

+0

http://mirrors.ibiblio.org/pub/mirrors/maven2/cglib/cglib-nodep/2.1_3/cglib-nodep-2.1_3.jar。そして、コントローラクラスに引数のないコンストラクタを追加する必要があります。 – splonk

2

ありがとうございます。私はコードをコンポーネントやサービスの中に書くという問題を解決しました。ですから、私は問題なしで@Transactionalを使うことができます。ここで

コード

方法コントローラ

@RequestMapping(value = "/pages/get",method=RequestMethod.GET) 
    public @ResponseBody String getPage(@RequestParam Long id){ 
     return new Gson().toJson(new ActionResult(pageBuilderService.buildAdapterFromPage(id))); 
    } 

iが供給される情報を取得するソリューションであるサービス

@Component(value="PageBuilderService") 
public class PageBuilderService { 

    @Autowired 
    private IPageRepository pageRepository; 


    public void setPageRepository(IPageRepository pageRepository) { 
     this.pageRepository = pageRepository; 
    } 

    @Transactional 
    public List<WidgetAdapter> buildAdapterFromPage(Long pageId){ 
     List<WidgetAdapter> adapters = new ArrayList<WidgetAdapter>(); 
     if(pageId!=null){ 
      Page page = pageRepository.getById(pageId); 
      if(page!=null && page.getWidgets()!=null){ 
       for(Widget widget: page.getWidgets()){ 
        adapters.add(WidgetFactory.FactoryMethodAdapter(widget)); 
       } 
      } 
     } 
     return adapters; 
    } 

} 

あります。私はそれが最善であるかどうかわからないが、私はそれが良い解決策だと思う。

+0

私の結果を掲載します。あなたは私の答えを受け入れることができますか? – splonk

+0

あなたはそれが働くのを手助けするために私は大騒ぎをします。ニース。 – splonk

+0

@musliサービスクラスのBTWには特別な注釈「@Service」があり、あなたのケースではより良いでしょう。 –

関連する問題