Refresh problems with JSF 2 view-scoped, EJB, CDI, JPA, and container-managed transactions on asynchronous file upload (working on GlassFish)
kwutzke Mar 15, 2012 12:40 PMHello all,
I'm currently developing a webapp based on JSF 2 view-scoped beans, EJB, CDI, JPA container-managed transactions, but I have an issue that I absolutely cannot solve on JBoss AS 7 (JBoss AS 7.1.0.Final). My webapp runs without any problems on GlassFish 3.1.2 (patched for http://java.net/jira/browse/GLASSFISH-18444).
I'm having a problem that I described over a month ago here: http://stackoverflow.com/questions/9129797/hibernate-4-lazyinitializationexception-on-el-expression
This is what started the avalanche... You can view the entity mappings here, but as I reduced my problem and I'm 100% sure that the mappings are correct.
Below is my JSF page, I can hardly reduce it further. The page shows two lists of files, each file associated with a company. Files can be deleted via a remove button while they can be added via a RichFaces 4 rich:fileUpload component below. The page shows individual (personal) files in the left column, external companies' files are shown in the right column (panelGrid):
The code for the left and right panels are exact copies, then just replacing "individual" with "external" etc. So both share the very same JSF code, but only use different methods on the JSF view-scoped bean:
{code:xml}<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<!-- this is for getting the GET request ID into the pqHome view-scoped bean, never mind it -->
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="pq" value="#{pqHome.pqId}" required="#{not facesContext.postback}">
<f:convertNumber integerOnly="#{true}" />
</f:viewParam>
</f:metadata>
</ui:define>
<h:head>
<title>Debug</title>
</h:head>
<h:body>
<h:form id="repo-form">
<h:panelGrid columns="2">
<rich:panel>
<f:facet name="header">
<h:outputText value="Individual Documents" />
</f:facet>
<rich:dataTable value="#{repoHome.individualDocuments}"
var="doc"
rows="15"
id="repo-idoc-datatable">
<f:facet name="header">
<rich:columnGroup>
<rich:column><h:outputText value="File Name" /></rich:column>
<rich:column><h:outputText value="Company" /></rich:column>
<rich:column><h:outputText value="Remove" /></rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="#{doc.fileName}" />
</rich:column>
<rich:column>
<h:outputText value="#{doc.company.name}" />
</rich:column>
<rich:column>
<h:commandLink action="#{repoHome.removeIndividualDocument(doc.id)}">
<h:graphicImage library="images/icons" name="cross.png" />
<f:ajax execute="@this" render=":repo-form:repo-idoc-datatable" />
</h:commandLink>
</rich:column>
<f:facet name="footer">
<rich:dataScroller />
</f:facet>
</rich:dataTable>
<rich:fileUpload fileUploadListener="#{repoHome.uploadIndividualDocument}"
acceptedTypes="doc,docx,pdf,txt,xls,ppt">
<a4j:ajax event="uploadcomplete"
execute="@none"
render=":repo-form:repo-idoc-datatable" />
</rich:fileUpload>
</rich:panel>
<rich:panel>
<f:facet name="header">
<h:outputText value="External Documents" />
</f:facet>
<rich:dataTable value="#{repoHome.externalDocuments}"
var="doc"
rows="15"
id="repo-edoc-datatable">
<f:facet name="header">
<rich:columnGroup>
<rich:column><h:outputText value="File Name" /></rich:column>
<rich:column><h:outputText value="Company" /></rich:column>
<rich:column><h:outputText value="Remove" /></rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="#{doc.fileName}" />
</rich:column>
<rich:column>
<h:outputText value="#{doc.company.name}" />
</rich:column>
<rich:column>
<h:commandLink action="#{repoHome.removeExternalDocument(doc.id)}">
<h:graphicImage library="images/icons" name="cross.png" />
<f:ajax execute="@this" render=":repo-form:repo-edoc-datatable" />
</h:commandLink>
</rich:column>
<f:facet name="footer">
<rich:dataScroller />
</f:facet>
</rich:dataTable>
<rich:fileUpload fileUploadListener="#{repoHome.uploadExternalDocument}"
acceptedTypes="doc,docx,pdf,txt,xls,ppt">
<a4j:ajax event="uploadcomplete"
execute="@none"
render=":repo-form:repo-edoc-datatable" />
</rich:fileUpload>
</rich:panel>
</h:panelGrid>
</h:form>
</h:body>
</ui:composition>{code}
Now what happens is really strange.
When deleting files with the X, a simple click will remove the documents from the DB and immediately re-render the respective lists (and only those) successfully. When adding an external document (right side), the item is added to the DB and the list is updated.
However, when uploading an individual document (left side), the item is added to the DB, but after the uploadIndividualDocument has run, the update of the list causes an exception:
{code}12:38:02,105 SEVERE [org.richfaces.log.Context] (http-localhost-127.0.0.1-8080-4) /debug.xhtml @48,59 value="#{doc.company.name}": org.hibernate.LazyInitializationException: could not initialize proxy - no Session: javax.el.ELException: /debug.xhtml @48,59 value="#{doc.company.name}": org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIOutput.getValue(UIOutput.java:169) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at org.richfaces.renderkit.RendererBase.renderChildren(RendererBase.java:276) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.AbstractTableBaseRenderer.encodeColumn(AbstractTableBaseRenderer.java:82) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.DataTableRenderer.encodeRow(DataTableRenderer.java:259) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.AbstractRowsRenderer.process(AbstractRowsRenderer.java:80) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.ajax4jsf.model.SequenceDataModel.walk(SequenceDataModel.java:65) [richfaces-core-api-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.component.UIDataAdaptor.walk(UIDataAdaptor.java:806) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.AbstractRowsRenderer.encodeRows(AbstractRowsRenderer.java:90) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.AbstractRowsRenderer.processRows(AbstractRowsRenderer.java:103) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.AbstractTableRenderer.encodeTableRows(AbstractTableRenderer.java:141) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.AbstractTableRenderer.doEncodeChildren(AbstractTableRenderer.java:195) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.renderkit.RendererBase.encodeChildren(RendererBase.java:157) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl$RenderVisitCallback.visit(ExtendedPartialViewContextImpl.java:504) [richfaces-core-impl-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.context.BaseExtendedVisitContext.invokeVisitCallback(BaseExtendedVisitContext.java:321) [richfaces-core-impl-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.component.UIDataAdaptor.visitTree(UIDataAdaptor.java:1319) [richfaces-components-ui-4.1.0.Final.jar:4.1.0.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIForm.visitTree(UIForm.java:344) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl.processPartialRenderPhase(ExtendedPartialViewContextImpl.java:272) [richfaces-core-impl-4.1.0.Final.jar:4.1.0.Final]
at org.richfaces.context.ExtendedPartialViewContextImpl.processPartial(ExtendedPartialViewContextImpl.java:194) [richfaces-core-impl-4.1.0.Final.jar:4.1.0.Final]
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:981) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:391) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.0.Final.jar:2.0.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
at org.jboss.solder.servlet.exception.CatchExceptionFilter.doFilter(CatchExceptionFilter.java:65) [solder-impl-3.1.0.Final.jar:3.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
at org.jboss.solder.servlet.event.ServletEventBridgeFilter.doFilter(ServletEventBridgeFilter.java:74) [solder-impl-3.1.0.Final.jar:3.1.0.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.10.Final.jar:]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.0.Final.jar:7.1.0.Final]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:154) [jboss-as-web-7.1.0.Final.jar:7.1.0.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.10.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.10.Final.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.10.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.10.Final.jar:]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_02]
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:149) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
* at de.poyry.pqgenerator.model.Company_$$_javassist_244.getName(Company_$$_javassist_244.java) [classes:]
at sun.reflect.GeneratedMethodAccessor1401.invoke(Unknown Source) [:1.7.0_02]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) [rt.jar:1.7.0_02]
at java.lang.reflect.Method.invoke(Unknown Source) [rt.jar:1.7.0_02]
at javax.el.BeanELResolver.getValue(BeanELResolver.java:302) [jboss-el-api_2.2_spec-1.0.0.Final.jar:1.0.0.Final]
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
at org.apache.el.parser.AstValue.getValue(AstValue.java:169) [jbossweb-7.0.10.Final.jar:]
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189) [jbossweb-7.0.10.Final.jar:]
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) [jsf-impl-2.1.5-jbossorg-1.jar:2.1.5-SNAPSHOT]
... 65 more{code}
The list update fails with the EL expression /debug.xhtml @48,59 value="#{doc.company.name}" for some reason.
Remember: both left and right are based on the same code and call nearly equaling methods on the same bean:
{code}public void uploadIndividualDocument(FileUploadEvent event) throws Exception
{
System.out.println(" ----------- begin uploadIndividualDocument -----------");
UploadedFile uf = event.getUploadedFile();
// associated entities
Company internal = companyManager.getInternalCompany();
User user = userManager.getCurrentUser();
// new individual doc plus associated company
IndividualDocument transientIndividualDocument = new IndividualDocument(internal.getId(), uf.getName(), uf.getData(), new Date(), user.getId());
transientIndividualDocument.setCompany(internal);
transientIndividualDocument.setUser(user);
docService.create(transientIndividualDocument);
// invalidate list
individualDocuments = null;
System.out.println(" ----------- end uploadIndividualDocument -----------");
}
public void uploadExternalDocument(FileUploadEvent event) throws Exception
{
System.out.println(" ------------ begin uploadExternalDocument ------------");
UploadedFile uf = event.getUploadedFile();
// get associated entities
Company company = companyManager.getInternalCompany();
// new external document plus associated company
ExternalDocument transientExternalDocument = new ExternalDocument(company.getId(), uf.getName(), null, uf.getData());
transientExternalDocument.setCompany(company);
docService.create(transientExternalDocument);
// invalidate list
externalDocumentGroups = null;
System.out.println(" ------------ end uploadExternalDocument ------------");
}{code}
As you can see the upload methods are almost equal, too. It's only that uploadIndividualDocument gets the current user from the session-scoped, CDI-injected userManager (not shown, via @Inject into the JSF managed bean) and sets it for the uploaded individual document.
There must be something wrong with my webapp or JBoss AS 7 has some issues, but I can't figure it out. I bet I'm doing something wrong. I have no idea how to continue with the exception I get.
Can anybody help?
Karsten
PS: server.log attached with trace enabled
-
server.log.zip 5.0 KB