Problems with list page, persistence, and detached entities
oberiko Jan 17, 2008 7:54 PMHello.
I seem to be doing something wrong with my Stateful Session Bean in that I can't seem to have it persist properly.
I have a list page where I want to delete previously entered users. I've put the @DataModel into the page scope, as I want it to be kept available until I leave the page.
package org.domain.myProject.session; import static javax.persistence.PersistenceContextType.EXTENDED; import java.util.List; import javax.ejb.Remove; import javax.ejb.Stateful; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.domain.myProject.entity.User; import org.domain.myProject.session.local.UserEditLocal; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Destroy; import org.jboss.seam.annotations.Factory; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.datamodel.DataModel; import org.jboss.seam.annotations.datamodel.DataModelSelection; import org.jboss.seam.faces.FacesMessages; import org.jboss.seam.log.Log; @Stateful @Name("userEdit") public class UserEditForm implements UserEditLocal { @Logger private Log log; @In FacesMessages facesMessages; @PersistenceContext(type = EXTENDED) private EntityManager em; @DataModelSelection @Out(required=false) private User user; @DataModel(scope=ScopeType.PAGE) private List<User> users; @SuppressWarnings("unchecked") @Factory("users") public void findUsers(){ log.info("********************************************* Finding the users"); if (users == null) log.info("users is null"); else if (users.size() == 0) log.info("users has a size of zero"); else log.info("Strange, because users has " +users.size() + " entries"); users = em.createQuery("from User u").getResultList(); } public void remove(){ log.info("Deleting user " +user.getName()); em.remove(user); users.remove(user); } public void update() { //TODO write the update method } @Destroy @Remove public void destroy() {} }
The following is my console log:
19:48:04,917 INFO [STDOUT] Hibernate: insert into User (id, name) values (null, ?) 19:48:04,917 INFO [STDOUT] Hibernate: call identity() 19:48:04,917 INFO [SaveUserAction] John was saved. 19:48:08,401 INFO [UserEditForm] ********************************************* Finding the users 19:48:08,401 INFO [UserEditForm] users is null 19:48:08,417 INFO [STDOUT] Hibernate: select user0_.id as id0_, user0_.name as name0_ from User user0_ 19:48:11,323 INFO [UserEditForm] ********************************************* Finding the users 19:48:11,323 INFO [UserEditForm] users is null 19:48:11,323 INFO [STDOUT] Hibernate: select user0_.id as id0_, user0_.name as name0_ from User user0_ 19:48:11,323 INFO [UserEditForm] Deleting user Vader 19:48:11,339 INFO [STDOUT] Hibernate: delete from User where id=? 19:48:26,495 INFO [UserEditForm] ********************************************* Finding the users 19:48:26,495 INFO [UserEditForm] users is null 19:48:26,495 INFO [STDOUT] Hibernate: select user0_.id as id0_, user0_.name as name0_ from User user0_ 19:48:26,495 INFO [UserEditForm] Deleting user Skywalker 19:48:26,511 INFO [STDOUT] Hibernate: delete from User where id=?
And this is the page I'm calling it from:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <f:view> <h:messages /> <h:form> <h:dataTable value="#{users}" var="user"> <h:column> <f:facet name="header"> <h:outputText value="Id" /> </f:facet> <h:outputText value="#{user.id}" /> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Name" /> </f:facet> <h:outputText value="#{user.name}" /> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Actions" /> </f:facet> <s:button action="#{userEdit.remove()}" value="S. Delete"/> <h:commandButton action="#{userEdit.remove()}" value="A. Delete" /> </h:column> </h:dataTable> </h:form> <s:button view="/user.xhtml" value="Return"/> </f:view> </html>
I think I understand that the s:button, since it's not passing the form back, is basically treating everything as a new page, which is why it's not being persisted (that's what I used in the above logs). When I try the <h:commandButton> though, I get the following:
Exception during request processing: Caused by javax.servlet.ServletException with message: "#{userEdit.remove()}: javax.ejb.EJBTransactionRolledbackException: Removing a detached instance org.domain.myProject.entity.User#7"
Is there a way, barring putting the page in the session scope, to keep the entities from being detached?