UnsupportedOperationException in PersistentBag when using s:convertEntity
gav_on_rails Mar 13, 2008 1:04 PMI've been trying to use the s:convertEntity tag to convert a user role to and from a selectManyListBox in a user admin page and periodically I get an UnsupportedOperationException when the PersistentBag is being cleared under the hood. I am making the connection between these two items based on the evidence and also if I remove the s:convertEntity tag then I no longer get this exception. The full exception is listed at the end.
It essentially boils down to the PersistentBag attempting to invoke the remove function on an instance of java.util.Arrays$ArrayList, which does not implement this method, and the base AbstractList throwing an UnsupportedOperationException. I'm guessing that somewhere in the convertEntity code an Arrays.asList is being used which returns an instance of this inner ArrayList.
To test all of this I have used the standard seam hotel booking example, injecting my code as required (hence the trans-user). My component.xml configuration is as follows:
Can anyone see an obvious misconfiguration or incorrect code usage, or should a Jira be raised for this one?
<?xml version="1.0" encoding="UTF-8"?> <components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:security="http://jboss.com/products/seam/security" xmlns:transaction="http://jboss.com/products/seam/transaction" xmlns:persistence="http://jboss.com/products/seam/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.0.xsd http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd"> <core:init jndi-pattern="@jndiPattern@" debug="true"/> <core:manager conversation-timeout="120000" concurrent-request-timeout="500" conversation-id-parameter="cid"/> <transaction:ejb-transaction /> <persistence:entity-manager-factory name="bookingDatabase"/> <persistence:managed-persistence-context name="entityManager" entity-manager-factory="#{bookingDatabase}"/> <security:identity authenticate-method="#{authenticator.authenticate}"/> </components>
The facelet page which uses s:convertEntity is as follows:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:s="http://jboss.com/products/seam/taglib"> <ui:composition template="content.xhtml"> <ui:define name="browserTitle"> <h:outputText value="#{messages['title.users']}"/> </ui:define> <ui:define name="pageTitle"> <h:outputText value="#{messages['title.users']}"/> </ui:define> <ui:define name="contentMenu"> <ui:include src="userMenu.xhtml"/> </ui:define> <ui:define name="mainContent"> <f:view> <h:form> <div style="display: block; width: 70%;"> <div style="background-color: #63a2bf; width:100%; height:30px"> <div> <h:outputText value="#{messages['title.userEdit']}"/> </div> </div> <div> <s:validateAll> <h:panelGrid columns="2"> <h:inputHidden id="userId" value="#{trans_user.id}"/> <h:outputText id="nameLabel" value="#{messages['title.user.name']}"/><h:inputText value="#{trans_user.name}" required="true"/> <h:outputText id="usernameLabel" value="#{messages['title.user.username']}"/><h:inputText value="#{trans_user.username}" required="true"/> <h:outputText id="passwordLabel" value="#{messages['title.user.password']}"/><h:inputSecret value="#{trans_user.password}" required="true"/> <h:outputText id="emailLabel" value="#{messages['title.user.email']}"/><h:inputText value="#{trans_user.email}" required="true"/> <h:outputText id="enabledLabel" value="#{messages['title.user.enabled']}"/><h:selectBooleanCheckbox value="#{trans_user.enabled}"/> <h:outputText id="rolesLabel" value="#{messages['title.user.roles']}"/> <h:selectManyListbox value="#{trans_user.roles}" id="selectRolesMenu" required="true"> <s:selectItems value="#{roles}" var="role" label="#{role.name}"/> <s:convertEntity/> </h:selectManyListbox> </h:panelGrid> </s:validateAll> <h:messages/> </div> <div style="background-color: #63a2bf; width:100%; height:30px"> <div style="float: right" class="submitButton"> <h:commandButton value="#{messages['controls.button.save']}" action="#{userAdmin.save}"/> </div> </div> </div> </h:form> </f:view> </ui:define> </ui:composition> </html>
And the UserAdminAction is as follows:
package com.mfuse.novo.transactions.ejb.actions; import static javax.persistence.PersistenceContextType.EXTENDED; import java.util.List; import javax.ejb.Stateful; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Begin; import org.jboss.seam.annotations.End; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Scope; import org.jboss.seam.annotations.datamodel.DataModel; import com.mfuse.novo.transactions.persistent.Role; import com.mfuse.novo.transactions.persistent.Trans_User; @Name("userAdmin") @Scope(ScopeType.CONVERSATION) @Stateful public class UserAdminAction extends BaseAction implements UserAdmin{ @DataModel List<Role> roles; @DataModel List<Trans_User> users; @In(required=false) @Out (required=false) Trans_User trans_user; @PersistenceContext(type=EXTENDED) private EntityManager entityManager; @Begin(nested=true) public void createNew(){ trans_user = new Trans_User(); } @Begin(nested=true) public void list(){ users = listAllUsers(); } public void selectUser(Trans_User user){ this.trans_user = entityManager.merge(user); } @End public void save(){ entityManager.persist(trans_user); } @Factory("roles") public void initRoles(){ roles = entityManager.createQuery("select r from Role r").getResultList(); } private List<Trans_User> listAllUsers(){ return entityManager.createQuery("select u from Trans_User u").getResultList(); } }
java.util.AbstractList.remove(AbstractList.java:144) java.util.AbstractList$Itr.remove(AbstractList.java:360) java.util.AbstractList.removeRange(AbstractList.java:559) java.util.AbstractList.clear(AbstractList.java:217) org.hibernate.collection.PersistentBag.clear(PersistentBag.java:366) org.hibernate.type.CollectionType.replaceElements(CollectionType.java:445) org.hibernate.type.CollectionType.replace(CollectionType.java:524) org.hibernate.type.TypeFactory.replace(TypeFactory.java:482) org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:340) org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:153) org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:126) org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53) org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677) org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661) org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665) org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227) org.jboss.ejb3.entity.ExtendedEntityManager.merge(ExtendedEntityManager.java:106) org.jboss.seam.persistence.EntityManagerProxy.merge(EntityManagerProxy.java:130) com.mfuse.novo.transactions.ejb.actions.UserAdminAction.selectUser(UserAdminAction.java:62) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112) org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166) org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:46) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.persistence.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:48) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:65) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.persistence.EntityManagerProxyInterceptor.aroundInvoke(EntityManagerProxyInterceptor.java:26) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.persistence.HibernateSessionProxyInterceptor.aroundInvoke(HibernateSessionProxyInterceptor.java:27) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118) org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.entity.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:71) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126) org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195) org.jboss.aop.joinpoint.uMethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:83) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77) org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106) org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) org.jboss.ejb3.stateful.StatefulContainer.localInvoke(StatefulContainer.java:206) org.jboss.ejb3.stateful.StatefulLocalProxy.invoke(StatefulLocalProxy.java:119) $Proxy127.selectUser(Unknown Source) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) org.jboss.seam.util.Reflections.invoke(Reflections.java:21) org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31) org.jboss.seam.intercept.ClientSideInterceptor$1.proceed(ClientSideInterceptor.java:76) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) org.jboss.seam.ejb.RemoveInterceptor.aroundInvoke(RemoveInterceptor.java:41) org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) org.jboss.seam.intercept.ClientSideInterceptor.invoke(ClientSideInterceptor.java:54) org.javassist.tmp.java.lang.Object_$$_javassist_5.selectUser(Object_$$_javassist_5.java) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) java.lang.reflect.Method.invoke(Method.java:597) org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:329) org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:274) org.jboss.el.parser.AstMethodSuffix.getValue(AstMethodSuffix.java:59) org.jboss.el.parser.AstMethodSuffix.invoke(AstMethodSuffix.java:65) org.jboss.el.parser.AstValue.invoke(AstValue.java:96) org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) org.jboss.seam.core.Expressions$2.invoke(Expressions.java:173) org.jboss.seam.navigation.Pages.callAction(Pages.java:636) org.jboss.seam.navigation.Pages.preRender(Pages.java:289) org.jboss.seam.jsf.SeamPhaseListener.preRenderPage(SeamPhaseListener.java:549) org.jboss.seam.jsf.SeamPhaseListener.beforeRenderResponse(SeamPhaseListener.java:460) org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseListener.java:144) org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:114) com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:222) com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144) javax.faces.webapp.FacesServlet.service(FacesServlet.java:245) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141) org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281) org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179) org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446) java.lang.Thread.run(Thread.java:619)