[jboss-user] [JBoss Seam] - Re: Problems with list page, persistence, and detached entit
Oberiko
do-not-reply at jboss.com
Fri Jan 18 12:14:42 EST 2008
Here's how I want it to work:
| * Save users to a database on the entry page
| * On navigation to the list page, pull users from the database into a list in the scope and display them
| * Do not call the database to update the list since it's in the scope
| * When leaving the page, remove all traces from the scope
|
|
| Now, I got that working with the following:
|
|
| | 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.Scope;
| | import org.jboss.seam.annotations.datamodel.DataModel;
| | import org.jboss.seam.annotations.datamodel.DataModelSelection;
| | import org.jboss.seam.contexts.Contexts;
| | import org.jboss.seam.faces.FacesMessages;
| | import org.jboss.seam.log.Log;
| |
| | @Stateful
| | @Name("userEdit")
| | @Scope(ScopeType.SESSION)
| | 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.getName());
| | em.remove(user);
| | users.remove(user);
| | }
| |
| | public void clear(){
| | log.info("Clearing the userEdit bean from the session");
| | Contexts.getSessionContext().remove("userEdit");
| | }
| |
| | public void update() {
| | //TODO write the update method
| | }
| |
| | @Destroy @Remove
| | public void destroy() {}
| | }
| |
|
|
| | package org.domain.myProject.session;
| |
| | import javax.ejb.Stateless;
| | import javax.persistence.EntityManager;
| | import javax.persistence.PersistenceContext;
| |
| | import org.domain.myProject.entity.User;
| | import org.domain.myProject.session.local.SaveUserLocal;
| | 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.contexts.Context;
| | import org.jboss.seam.contexts.Contexts;
| |
| | import org.jboss.seam.faces.FacesMessages;
| | import org.jboss.seam.log.Log;
| |
| | @Stateless
| | @Name("saveUser")
| | public class SaveUserAction implements SaveUserLocal {
| |
| | @Logger
| | private Log log;
| |
| | @In
| | FacesMessages facesMessages;
| |
| | @PersistenceContext
| | private EntityManager em;
| |
| | /* We have an '@Out' on this to push back user (after any modifications we make
| | * in our bean here) onto the page. Since we're nullifying user in our save method,
| | * we need to state that it's not required to have any value.
| | */
| | @In @Out(required=false)
| | private User user;
| |
| | public void saveUser() {
| | //Simple persisting with the EntityManager
| | em.persist(user);
| |
| | //Note that the id of our user was generated and populated.
| | facesMessages.add("User was saved with an id of "+ user.getId());
| |
| | log.info(user.getName() +" was saved.");
| |
| | //We're nullifying user so that the page is blank after saving.
| | user = null;
| |
| | //All items in the session context, only here for testing the list page
| | for (String s:Contexts.getSessionContext().getNames()){
| | if (s.startsWith("org.jboss") || s.startsWith("javax") || s.startsWith("org.ajax4jsf"))
| | continue;
| | log.info(s + " is in the session");
| | }
| | }
| | }
| |
| |
|
| And my .xhtml files
|
| | <!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:form>
| | <s:validateAll>
| | Name:
| | <h:inputText value="#{user.name}" required="true"
| | requiredMessage="You need to enter a name"/>
| | <br />
| | <h:commandButton value="Save" action="#{saveUser.saveUser()}" />
| | <s:button value ="List" view="/listUsers.xhtml"/>
| | </s:validateAll>
| | </h:form>
| | <h:messages />
| | </f:view>
| |
| | </html>
| |
|
|
| | <!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="H. Delete" />
| | </h:column>
| | </h:dataTable>
| | </h:form>
| | <s:button action="#{userEdit.clear()}" view="/user.xhtml" value="S. Return"/>
| | </f:view>
| |
| | </html>
| |
|
| And here's my log (trimmed for brevity)
|
| | 11:41:01,347 INFO [SaveUserAction] Luke was saved.
| | 11:41:06,809 INFO [SaveUserAction] Skywalker was saved.
| | 11:41:11,567 INFO [SaveUserAction] Darth was saved.
| | 11:41:15,417 INFO [SaveUserAction] Vader was saved.
| | 11:41:18,813 INFO [SaveUserAction] Yoda was saved.
| | 11:41:25,605 INFO [SaveUserAction] I forgot about Yoda! was saved.
| | 11:41:40,770 INFO [UserEditForm] ********************************************* Finding the users
| | 11:41:40,770 INFO [UserEditForm] users is null
| | 11:41:45,043 INFO [UserEditForm] Deleting I forgot about Yoda!
| | 11:41:48,548 INFO [UserEditForm] Deleting Darth
| | 11:41:54,762 INFO [UserEditForm] Clearing the userEdit bean from the session
| | 11:42:04,684 INFO [SaveUserAction] Solo was saved.
| | 11:45:11,096 INFO [UserEditForm] ********************************************* Finding the users
| | 11:45:11,096 INFO [UserEditForm] users is null
| | 11:45:18,702 INFO [UserEditForm] Deleting Vader
| |
|
| Now, with that working (though not as cleanly as I'd like), I started trying to figure out what I could ditch to make it simpler.
|
| I started by getting rid of the page scope on my DataModel and adding a check to see the users being removed from the session:
|
|
| | ...
| | // @DataModel(scope=ScopeType.PAGE)
| | @DataModel
| | private List<User> users;
| | ...
| | public void clear(){
| | log.info("Clearing the userEdit bean from the session");
| | Contexts.getSessionContext().remove("userEdit");
| |
| | if (Contexts.getSessionContext().isSet("users")){
| | log.info("Clearing the users from the session");
| | Contexts.getSessionContext().remove("users");
| |
| | if (Contexts.getSessionContext().isSet("users"))
| | log.info("You're still here?");
| | }
| | ...
| |
|
| But for some reason, now the "users" keeps getting plugged back into the session, even though I removed (and verified removing) it.
|
|
| | 11:51:23,638 INFO [SaveUserAction] Jean Luc was saved.
| | 11:51:27,457 INFO [SaveUserAction] Picard was saved.
| | 11:51:30,696 INFO [SaveUserAction] Data was saved.
| | 11:51:34,155 INFO [SaveUserAction] Worf was saved.
| | 11:51:37,943 INFO [UserEditForm] ********************************************* Finding the users
| | 11:51:37,943 INFO [UserEditForm] users is null
| | 11:51:51,058 INFO [UserEditForm] Deleting Picard
| | 11:52:00,119 INFO [UserEditForm] Deleting Data
| | 11:52:04,908 INFO [UserEditForm] Clearing the userEdit bean from the session
| | 11:52:04,908 INFO [UserEditForm] Clearing the users from the session
| | 11:52:28,634 INFO [SaveUserAction] Locutus was saved.
| | 11:52:28,634 INFO [SaveUserAction] users is in the session
| | 11:52:56,758 INFO [SaveUserAction] Q was saved.
| | 11:52:56,758 INFO [SaveUserAction] users is in the session
| |
|
| So it looks like I need the page scope.
|
| So, is my top way, of putting the whole bean in the session-scope and the data model in the page-scope the cleanest way of doing this?
|
| I'm trying to avoid the session-scope as much as possible since, coming from a Struts background, I know the hassle (in both maintenaince and leaks) it can cause, especially when several other people start working on something with you.
|
| Would it be of any use to start looking at creating a Seam Managed Persistence Context? I'm using EAR deployment (so I can use EJB's) and I know that I can't use the default of:
| @In private EntityManager entityManager
| Due to http://jira.jboss.org/jira/browse/JBIDE-1409?decorator=printable
|
|
| Also, why does "users" keep popping back into the session when not assigned to the page-scope, even after removing it?
|
| I know this is all quite the mouthful, but anyone have any suggestions?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4121369#4121369
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4121369
More information about the jboss-user
mailing list