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?