2014-02-01 1 views
1

Я уже некоторое время искал. Я обнаружил, что OpenSessionInViewFilter должен делать трюк, но в любом случае кажется, что он не работает в моем случае.LazyInitializationException с Spring Roo jsf сгенерированное приложение

Я также нашел несколько сообщений, в которых говорится, что ручная инициализация помогает, но я не понимаю, как это сделать, учитывая, что репозиторий - это интерфейс и, кажется, он реализован где-то, я не знаю (я, кажется, неспособный найти, где начать искать этот пункт).

Я работаю с Spring Roo - jsf - hibernate application. В какой-то странице я получаю следующее сообщение об ошибке в консоли:

СИЛЬНЫЙ: javax.el.ELException: /pages/dossier.xhtml @ 76,72 значение = "# {} dossierDescription.documentTypesList": Ошибка чтение 'documentTypesList' ан-эль-Tipo co.qcsc.spatha.domain.dossier.DossierDescription фев 01, 2014 4:50:43 PM com.sun.faces.context.PartialViewContextImpl $ PhaseAwareVisitCallback визит СИЛЬНЫЙ: javax.el .ELException: /pages/dossier.xhtml @ 76,72 value = "# {dossierDescription.documentTypesList}": Ошибка чтения 'documentTypesList' en el tipo co.qcsc.spatha.doma in.dossier.DossierDescription

Поиск по той причине, я прибыл к этому:

org.hibernate.LazyInitializationException: не удалось инициализировать лениво коллекцию роли: co.qcsc.spatha.domain .dossier.DossierDescription.documentTypes, может не инициализировать прокси - не сессии

Поскольку это Роо, уже с OpenSessionInViewFilter, в web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> 
    <display-name>spatha</display-name> 
    <description>Roo generated spatha application</description> 
    <context-param> 
    <param-name>defaultHtmlEscape</param-name> 
    <param-value>true</param-value> 
    </context-param> 
    <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value> 
    </context-param> 
    <context-param> 
    <param-name>primefaces.THEME</param-name> 
    <param-value>cupertino</param-value> 
    </context-param> 
    <filter> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
    <servlet-name>Faces Servlet</servlet-name> 
    </filter-mapping> 
    <filter> 
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> 
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    <listener> 
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class> 
    </listener> 
    <servlet> 
    <servlet-name>Faces Servlet</servlet-name> 
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>Faces Servlet</servlet-name> 
    <url-pattern>*.jsf</url-pattern> 
    </servlet-mapping> 

    <servlet> 
    <servlet-name>ReportServlet</servlet-name> 
    <servlet-class>co.qcsc.spatha.web.servlet.ReportServlet</servlet-class> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>ReportServlet</servlet-name> 
    <url-pattern>/clients.pdf</url-pattern> 
    </servlet-mapping> 

    <session-config> 
    <session-timeout>10</session-timeout> 
    </session-config> 
    <welcome-file-list> 
    <welcome-file>index.html</welcome-file> 
    </welcome-file-list> 
</web-app> 

Класс:

@RooJavaBean 
@RooToString 
@RooJpaEntity 
public class DossierDescription { 

    @NotNull 
    @Size(min = 2) 
    private String name; 

    @ManyToOne 
    private Client client; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "dossierDescription", fetch = FetchType.LAZY) 
    private Set<DocumentType> documentTypes = new HashSet<DocumentType>(); 

    @NotNull 
    private Boolean valid; 

    public List<DocumentType> getDocumentTypesList() { 
     List<DocumentType> list = new ArrayList<DocumentType>(); 
     list.addAll(getDocumentTypes()); 
     return list; 
    } 

} 

Поскольку я Repository и услуг слоев, у меня есть, как вы могли себе представить:

public class DossierDescriptionServiceImpl implements DossierDescriptionService { 
} 

@RooJpaRepository(domainType = DossierDescription.class) 
public interface DossierDescriptionRepository { 
} 

аспект для репозиторием (это тот, который я не понимают вообще):

privileged aspect DossierDescriptionRepository_Roo_Jpa_Repository { 

    declare parents: DossierDescriptionRepository extends JpaRepository<DossierDescription, Long>; 

    declare parents: DossierDescriptionRepository extends JpaSpecificationExecutor<DossierDescription>; 

    declare @type: DossierDescriptionRepository: @Repository; 

} 

В соответствующей части XHTML у меня есть:

<h:panelGrid id="createPanelGrid" columns="2" styleClass="dialog" columnClasses="col1,col2"> 
    <h:outputText value="#{app.label_specialty}" /> 
    <p:autoComplete id="specialtyInput" 
      value="#{dossierMB.dossier.specialty.specialty}" 
      completeMethod="#{dossierMB.completeSpecialty}" 
      dropdown="true" var="specialty" required="false" 
      itemLabel="#{specialty.name}" itemValue="#{specialty}" 
      converter="co.qcsc.spatha.web.mb.converter.SpecialtyConverter"/> 
    <p:tabView id="dossierDescriptionsTabView" var="dossierDescription" 
      value="#{dossierMB.client.dossierDescriptionsList}"> 
     <p:tab id="dossierDescriptionTab" title="#{dossierDescription.name}"> 
      <p:dataTable id="dossierList" value="#{dossierDescription.documentTypesList}" 
        var="documentType" resizableColumns="false" paginator="true" 
        paginatorTemplate=" {CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" 
        rowsPerPageTemplate="5,10,25,50" rows="10"> 
       <p:column> 
        <f:facet name="header"> 
         <h:outputText value="#{app.label_documentType}" /> 
        </f:facet> 
        <h:outputText value="#{documentType.name}"/> 
       </p:column> 
      </p:dataTable> 
     </p:tab> 
    </p:tabView> 
    </h:panelGrid> 

И correspondant ManagedBean является:

@RooSerializable 
@RooJsfManagedBean(entity = Dossier.class, beanName = "dossierMB") 
public class DossierMB { 

    @Autowired 
    PurchaseOrderService poService; 

    @Autowired 
    ClientService clientService; 

    @Autowired 
    SpecialtyService specialtyService; 

    private Client client; 
    private List<PurchaseOrder> purchaseOrders; 
    private PurchaseOrder purchaseOrder; 
    private Dossier dossier; 
    private OrderItem orderItem; 

    public List<Client> getClients() { 
     return clientService.findAllClients(); 
    } 

    public String displayConsultPO() { 
     return "consultPO"; 
    } 

    public String findPurchaseOrders() { 
     purchaseOrders = poService.findPurchaseOrderByClient(client); 
     return "consultPO"; 
    } 

    public String displayCreateDialog() { 
     if (orderItem.getDossiers() == null){ 
      orderItem.setDossiers(new HashSet<Dossier>()); 
     } 
     dossier = new Dossier(); 
     return "dossier"; 
    } 

    public List<Specialty> completeSpecialty(String query) { 
     List<Specialty> suggestions = new ArrayList<Specialty>(); 
     for (Specialty specialty : specialtyService.findAllSpecialtys()) { 
      String specialtyStr = String.valueOf(specialty.getName()); 
      if (specialtyStr.toLowerCase().contains(query.toLowerCase())) { 
       suggestions.add(specialty); 
      } 
     } 
     return suggestions; 
    } 

    public Client getClient() { 
     return client; 
    } 

    public void setClient(Client client) { 
     this.client = client; 
    } 

    public List<PurchaseOrder> getPurchaseOrders() { 
     return purchaseOrders; 
    } 

    public void setPurchaseOrders(List<PurchaseOrder> purchaseOrders) { 
     this.purchaseOrders = purchaseOrders; 
    } 

    public PurchaseOrder getPurchaseOrder() { 
     return purchaseOrder; 
    } 

    public void setPurchaseOrder(PurchaseOrder purchaseOrder) { 
     this.purchaseOrder = purchaseOrder; 
    } 

    public OrderItem getOrderItem() { 
     return orderItem; 
    } 

    public void setOrderItem(OrderItem orderItem) { 
     this.orderItem = orderItem; 
    } 
} 

Для завершения, это соответствующая часть ApplicationContext.XML:

<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
    id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 
<tx:annotation-driven mode="aspectj" 
    transaction-manager="transactionManager" /> 
<bean 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    id="entityManagerFactory"> 
    <property name="persistenceUnitName" value="persistenceUnit" /> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 

StackTrace:

WARNING: #{dossierMB.displayCreateDialog}: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: co.qcsc.spatha.domain.dossier.DossierDescription.documentTypes, could not initialize proxy - no Session 
javax.faces.FacesException: #{dossierMB.displayCreateDialog}: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: co.qcsc.spatha.domain.dossier.DossierDescription.documentTypes, could not initialize proxy - no Session 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
    at javax.faces.component.UIData.broadcast(UIData.java:1093) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:180) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:722) 
Caused by: javax.faces.el.EvaluationException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: co.qcsc.spatha.domain.dossier.DossierDescription.documentTypes, could not initialize proxy - no Session 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
    ... 31 more 
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: co.qcsc.spatha.domain.dossier.DossierDescription.documentTypes, could not initialize proxy - no Session 
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124) 
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180) 
    at co.qcsc.spatha.web.mb.DossierMB.displayCreateDialog(DossierMB.java:68) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.apache.el.parser.AstValue.invoke(AstValue.java:278) 
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) 
    ... 32 more 

Спасибо за чтение,

+0

посмотреть здесь сообщение в блоге я написал для некоторых плюсов и минусов для OpenSessionInView http://blog.jhades.org/open-session-in-view-pattern-pros- и-минусы –

ответ

0

Это означает, что кто-то закрывает диспетчер сущностей, созданный OpenEntityManagerInView, прежде чем он достигнет вид рендеринга фазы.

OpenEntityManagerInView совместим только с некоторыми менеджерами транзакций, то javadoc упоминает JpaTransactionManager и JtaTransactionManager, взглянуть на него для получения более подробной информации.

Это нормально, потому что привязка менеджера сущности к потоку недостаточна, менеджер транзакций должен знать, что он должен выглядеть первым в потоке перед созданием нового EM.

Должен быть уровень координации и совместимости между менеджером транзакций и фильтром.

Таким образом, одно объяснение заключается в том, что используемый диспетчер транзакций несовместим с OpenEntityManagerInView.

Другим объяснением является то, что диспетчер объектов закрывается в коде приложения напрямую, используя EntityManager.close().

Во всех случаях одна вещь кажется уверенной: причина в том, что кто-то закрывает диспетчер сущности.

EDIT:

Проблема также может быть вызван сессией область действия боба, который инициализируется в одном запросе, слева в сессии и доступ в новом запросе HTTP. Начальный сеанс по первому запросу закрывается, когда первый запрос завершается, что приводит к ленивому исключению инициализации во втором запросе.

Вы можете устранить это далее:

  • проверки, если менеджер транзакций совместим с фильтром

  • убедитесь em.close() не вручную вызывается в приложении

  • положить точка останова на EntityManagerImpl.close(), прокрутите вниз по трассе стека, когда он попал, и посмотрите, кто ее закрывает.

+0

Привет @jhadesdev, Спасибо за ваш ответ. Я проверил, и transactionManager (как вы можете видеть в редакции вопроса) - JpaTransactionManager. И нет, у меня нет кода entityManager.close(). Есть идеи? Меня смущает аннотированный интерфейс Repository. Потому что этот аспект кажется загадочным для меня. –

+0

Другим возможным объяснением является то, что некоторый объект сущности спящего режима поддерживается в HTTP-сеансе между HTTP-запросами, в этом случае OpenEntityManagerInView также не решит эту проблему. В таком случае вы можете опубликовать полный стек из LazyInitializationException? (если это слишком долгое использование pastebin.com) –

+0

Я имею в виду, что если вы опубликуете полный стек, мы лучше увидим, что происходит, кто вызывает тот объект, когда –

0

Проблема заключается в том, когда вы пытаетесь получить доступ к documentTypes нет сессии по данным нагрузочных из БД.Таким образом, у вас есть 3 решения:

  1. Измените погрузо-режим documentTypes нетерпеливым
  2. Используйте @PostLoad для загрузки списка (что почти то же самое, чем предыдущие варианты)
  3. Силу, чтобы создать соединение перед доступом ленивого свойства:
 


    @Transactional 
    public List getDocumentTypesList() { 
     DossierDescription connected = DossierDescription.findDossierDescription(getId); 
     List list = new ArrayList(); 
     list.addAll(connected.getDocumentTypes()); 
     return list; 
    } 

 

 Смежные вопросы

  • Нет связанных вопросов^_^