[jboss-user] [JBoss Seam] - Re: EntityManger-per-user-session...

bkyrlach do-not-reply at jboss.com
Wed Nov 8 11:43:35 EST 2006


Okay... so why doesn't this work...

First I create a parent and outject it to the Session context...

View...


  |     <h:form>
  |       <table>
  |         <tr>
  |           <td>Name:</td>
  |           <td><h:inputText value="#{newParent.name}"/></td>
  |         </tr>
  |         <tr>
  |           <td>Submit:</td>
  |           <td><h:commandButton action="#{parentActions.createParent}"/></td>
  |         </tr>
  |       </table>      
  |     </h:form>
  | 

Model...


  | @Entity
  | @Name("parent")
  | @Scope(ScopeType.SESSION)
  | @Role(name="newParent", scope=ScopeType.EVENT)
  | public class Parent implements Serializable
  | {
  | ...
  | ...
  | ...
  |     @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="parent")
  |     public List<Child> getChildren()
  |     {
  |         return children;
  |     }
  |     public void setChildren(List<Child> children)
  |     {
  |         this.children = children;
  |     }
  | ...
  | ...
  | ...
  | }
  | 

Action...


  | package sample.business.pc;
  | 
  | import javax.ejb.Stateless;
  | import javax.interceptor.Interceptors;
  | import javax.persistence.EntityManager;
  | import javax.persistence.PersistenceContext;
  | 
  | import org.jboss.seam.annotations.In;
  | import org.jboss.seam.annotations.Name;
  | import org.jboss.seam.annotations.Out;
  | import org.jboss.seam.contexts.Contexts;
  | import org.jboss.seam.ejb.SeamInterceptor;
  | 
  | import sample.model.pc.Parent;
  | 
  | @Stateless
  | @Name("parentActions")
  | @Interceptors(SeamInterceptor.class)
  | public class ParentActionsImpl implements ParentActions
  | {
  |     @In(create=true)
  |     EntityManager em;
  |     
  |     @Out(required=false)
  |     Parent parent;
  |     
  |     @In(required=false)
  |     Parent newParent;
  |     
  |     public String createParent()
  |     {
  |         em.persist(newParent);
  |         parent = newParent;
  |         return "/pc/viewer.xhtml";
  |     }
  |     
  |     public Parent getParent(Long id)
  |     {
  |         return em.find(Parent.class, id);
  |     }
  | }
  | 

And then go to create a child...

View...


  |     <h:form>
  |       <table>
  |         <tr>
  |           <td>Name:</td>
  |           <td><h:inputText value="#{child.name}"/></td>
  |         </tr>
  |         <tr>
  |           <td>Submit:</td>
  |           <td><h:commandButton action="#{childActions.createChild}"/></td>
  |         </tr>
  |       </table>      
  |     </h:form>
  | 

Model...


  | @Entity
  | @Name("child")
  | @Scope(ScopeType.CONVERSATION)
  | public class Child implements Serializable
  | {
  | ...
  | ...
  | ...
  |     @ManyToOne
  |     public Parent getParent()
  |     {
  |         return parent;
  |     }
  |     public void setParent(Parent parent)
  |     {
  |         this.parent = parent;
  |     }
  | ...
  | ...
  | ...
  | }
  | 

Action...


  | package sample.business.pc;
  | 
  | import java.io.Serializable;
  | import java.util.ArrayList;
  | import java.util.List;
  | 
  | import javax.ejb.Remove;
  | import javax.ejb.Stateful;
  | import javax.interceptor.Interceptors;
  | import javax.persistence.EntityManager;
  | 
  | import org.jboss.seam.ScopeType;
  | import org.jboss.seam.annotations.Begin;
  | import org.jboss.seam.annotations.Destroy;
  | import org.jboss.seam.annotations.End;
  | 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.ejb.SeamInterceptor;
  | 
  | import sample.model.pc.Child;
  | import sample.model.pc.Parent;
  | 
  | @Stateful
  | @Name("childActions")
  | @Scope(ScopeType.CONVERSATION)
  | @Interceptors(SeamInterceptor.class)
  | public class ChildActionsImpl implements ChildActions, Serializable
  | {
  |     @In(create=true)
  |     EntityManager em;
  |     
  |     @In
  |     Parent parent;
  |     
  |     @In(required=false)
  |     @Out(required=false)
  |     Child child;
  |     
  |     @In(create=true)
  |     ParentActions parentActions;
  |     
  |     @Begin
  |     public String preCreateChild()
  |     {
  |         parent = parentActions.getParent(parent.getId()); 
  |         return "/pc/createChild.xhtml";
  |     }
  |     
  |     @End
  |     public String createChild()
  |     {
  |         child.setParent(parent);
  |         List<Child> children = parent.getChildren();
  |         if(children == null)
  |         {
  |             children = new ArrayList<Child>();
  |         }
  |         children.add(child);
  |         parent.setChildren(children);
  |         return "/pc/viewer.xhtml";
  |     }
  | ...
  | ...
  | ...
  | }
  | 

So, when preCreate is called, I call ParentActions and get them to return me an attached instance of the current Parent using em.find(Parent.class, parent.getId()); This is inside a long runnig conversation, so you tell me that the same EntityManager instance is used for the entire conversation. Then, after injecting the newly created Child, I set it's parent, add it to the parents collection, and now I'm supposing the following should happen...

EntityManager discovers Parent is dirty and goes to merge it. Since Parents child collection is marked as cascade all, all of parents child elements should also be persisted, and my new child should be visible in the database. This isn't what's happening though.

Help?

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3984228#3984228

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3984228



More information about the jboss-user mailing list