jsf2/RF4 'a4j:commandButton' oncomplete processing nullifies backing bean's member variables
clahrcwr Feb 11, 2013 10:54 AMI have an entry form with Seam-generated Entity and EntityHome type backing beans. Since the user wants a confirmation pop up dialog before saving the entered data, I've replaced the auto-generated 'h:commandButton' with a 'a4j:commandButton' and attached a modal panel to its 'oncomplete' event:
the Edit.xhtml entry form bit:
. . . . . <div class="actionButtons"> <a:commandButton id="save" value="Save" oncomplete="#{rich:component('confirmCreatePanel')}.show();" disabled="#{!userProjectRolesHome.wired}" rendered="#{!userProjectRolesHome.managed}"> <s:conversationId/> </a:commandButton> </div> <rich:popupPanel modal="true" id="confirmCreatePanel" moveable="false" resizeable="false" height="120"> <f:facet name="header">Confirm</f:facet> <div class="actionButtons"> <rich:panel style="align:center;"> <h:outputText value="Are you sure you want to create this ?" /> <table width="100%"> <tbody> <tr> <td align="center" width="50%"> <a:commandButton type="submit" value="Yes" action="#{userProjectRolesHome.persist}" oncomplete="#{rich:component('confirmCreatePanel')}.hide()"/> </td> <td align="center" width="50%"> <a:commandButton type="submit" value="No" onclick="#{rich:component('confirmCreatePanel')}.hide()"/> </td> </tr> </tbody> </table> </rich:panel> </div> </rich:popupPanel>
the backing entity bean:
package clahrc.entity; // Generated 22-Oct-2012 11:15:44 by Hibernate Tools 3.4.0.CR1 import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.validation.constraints.NotNull; /** * UserProjectRoles generated by hbm2java */ @Entity @Table(name="user_project_roles",catalog="clahrc2") public class UserProjectRoles implements java.io.Serializable { private static final long serialVersionUID = 1L; private UserProjectRolesId id; private Users users; private Projects projects; private Roles roles; public UserProjectRoles() { } public UserProjectRoles(UserProjectRolesId id, Users users, Projects projects, Roles roles) { this.id = id; this.users = users; this.projects = projects; this.roles = roles; } @EmbeddedId @AttributeOverrides( { @AttributeOverride(name="userId", column=@Column(name="User_ID", nullable=false) ), @AttributeOverride(name="projectId", column=@Column(name="Project_ID", nullable=false) ) } ) @NotNull public UserProjectRolesId getId() { return this.id; } public void setId(UserProjectRolesId id) { this.id = id; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="User_ID", nullable=false, insertable=false, updatable=false) @NotNull public Users getUsers() { return this.users; } public void setUsers(Users users) { this.users = users; } @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="Project_ID", nullable=false, insertable=false, updatable=false) @NotNull public Projects getProjects() { return this.projects; } public void setProjects(Projects projects) { this.projects = projects; } @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="Role_ID", nullable=false) @NotNull public Roles getRoles() { return this.roles; } public void setRoles(Roles roles) { this.roles = roles; } }
and this is the backing bean's Home class 'userProjectRolesHome' :
package clahrc.session; import java.util.Map; import javax.faces.model.SelectItem; import javax.persistence.NoResultException; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Transactional; import org.jboss.seam.framework.EntityHome; import org.jboss.seam.international.StatusMessage; import org.jboss.seam.international.StatusMessages; import org.jboss.seam.log.Log; import clahrc.entity.Projects; import clahrc.entity.Roles; import clahrc.entity.UserProjectRoles; import clahrc.entity.UserProjectRolesId; import clahrc.entity.Users; @Name("userProjectRolesHome") public class UserProjectRolesHome extends EntityHome<UserProjectRoles> { @In(create = true) UsersHome usersHome; @In(create = true) ProjectsHome projectsHome; @In(create = true) RolesHome rolesHome; private static final long serialVersionUID = 1L; public void setUserProjectRolesId(UserProjectRolesId id) { setId(id); } public UserProjectRolesId getUserProjectRolesId() { return (UserProjectRolesId) getId(); } public UserProjectRolesHome(){ setUserProjectRolesId( new UserProjectRolesId() ); } @Override public boolean isIdDefined() { if ( getUserProjectRolesId().getUserId() == 0 ) return false; if ( getUserProjectRolesId().getProjectId() == 0 ) return false; return true; } @Override protected UserProjectRoles createInstance() { UserProjectRoles userProjectRoles = new UserProjectRoles(); userProjectRoles.setId( new UserProjectRolesId() ); return userProjectRoles; } public void load() { if (isIdDefined()) { wire(); } } public void wire() { getInstance(); Users users = usersHome.getDefinedInstance(); if ( users != null ) { getInstance().setUsers( users ); getInstance().getId().setUserId( users.getId() ); } Projects projects = projectsHome.getDefinedInstance(); if ( projects != null ) { getInstance().setProjects( projects ); getInstance().getId().setProjectId( projects.getId() ); } Roles roles=rolesHome.getDefinedInstance(); if ( roles != null ) { getInstance().setRoles(roles); } } public boolean isWired() { if ( getInstance().getUsers() == null ) return false; if ( getInstance().getProjects() == null ) return false; if ( getInstance().getRoles() == null ) return false; return true; } public UserProjectRoles getDefinedInstance() { return isIdDefined() ? getInstance() : null; } @Override public String persist() { String PersistResult = null; try { PersistResult = super.persist(); // user project role creation successful - email notification //mailSender.sendNewRole(......); } catch ( Exception exc ) { //... log the exception return PersistResult; } }
When clicked on the 'Save' button the 'confirmCreatePanel' pops up OK, but then when the user clicks on the mod.panel 'Yes' and the 'persist()' is called I get an Exception complaining about the member variables 'users', 'projects' and 'roles' being 'null'.
If I call 'persist()' from the 'action' attribute of the either the 'a4j:commandButton' or 'h:commandButton' everything works OK. the 'oncomplete' processing messes the things up and it used to work.
This same code works with Seam 2.2.2.Final/RF3.3.3/JSF1.2. it's not working now after an upgrade to Seam2.3.0.Final/RF4/JSF2 what's changed here ?
2013-02-06 12:57:50,394 ERROR [uk.ac.imperial.clahrc.session.UserProjectRolesHome] user-project-role persisting or emailing failed: javax.validation.ConstraintViolationException: Validation failed for classes [clahrc.entity.UserProjectRoles] during persist time for groups [javax.validation.groups.Default, ] List of constraint violations:[ ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=projects, rootBeanClass=class clahrc.entity.UserProjectRoles, messageTemplate='{javax.validation.constraints.NotNull.message}'} ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=users, rootBeanClass=class clahrc.entity.UserProjectRoles, messageTemplate='{javax.validation.constraints.NotNull.message}'} ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=roles, rootBeanClass=class clahrc.entity.UserProjectRoles, messageTemplate='{javax.validation.constraints.NotNull.message}'} ] at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:159) at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:94) at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:175) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:73) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081) at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:973) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.jboss.seam.persistence.EntityManagerInvocationHandler.invoke(EntityManagerInvocationHandler.java:46) at $Proxy77.flush(Unknown Source) at org.jboss.seam.framework.EntityHome.persist(EntityHome.java:85) at clahrc.session.UserProjectRolesHome.persist(UserProjectRolesHome.java:104) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.jboss.seam.util.Reflections.invoke(Reflections.java:22) at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:77) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97) at org.jboss.seam.util.Work.workInTransaction(Work.java:61) at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:186) at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:104) at clahrc.session.UserProjectRolesHome_$$_javassist_seam_21.persist(UserProjectRolesHome_$$_javassist_seam_21.java) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335) at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348) at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58) at org.jboss.el.parser.AstValue.invoke(AstValue.java:96) at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) at javax.faces.component.UICommand.broadcast(UICommand.java:315) 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:329) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53) at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:397) at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) at java.lang.Thread.run(Thread.java:662)