I looked at the link that Pete pointed out and the way I read Gavin's comment 
in there I didn't see why @DataModelSelection shouldn't work.  If true, 
enlightenment appreciated.

Anyway, what I'm trying to do is have a page that uses nested iteration to let 
a user operate on both sides of a many-to-many relationship.  I'm inclined to 
agree with Gavin that "I'm not convinced that h:dataTable isn't a little 
over-engineered for what it does ;-)".  In particular for my application, I 
don't want the HTML table from <h:dataTable>.

I've created an abstracted little Seam app that gets at what I'm trying to do: 
iterate over an iteration and be able to do an operation over either the inner 
or outer iteration.  When pressing the "rename" buttons, the value that I 
expect to be injected is not there (the log.error() calls below are triggered). 
 I believe that this is a self-contained, compilable, runnable, and suitable 
small abstraction for a test case or bug report, if that's helpful.  Code goes 
into a package called com.orgmob.play .

Is this a bug or can anybody say how to do this?

As always, pointing out bugs of mine and/or pointers to existing explanation 
humbly and gratefully appreciated.

Foo.java:


  | package com.orgmob.play;
  | 
  | import java.io.Serializable;
  | import java.util.ArrayList;
  | import java.util.HashSet;
  | import java.util.List;
  | import java.util.Set;
  | 
  | import javax.persistence.CascadeType;
  | import javax.persistence.Column;
  | import javax.persistence.Entity;
  | import javax.persistence.GeneratedValue;
  | import javax.persistence.Id;
  | import javax.persistence.JoinColumn;
  | import javax.persistence.JoinTable;
  | import javax.persistence.ManyToMany;
  | import javax.persistence.Table;
  | import javax.persistence.Transient;
  | 
  | import org.jboss.seam.annotations.Name;
  | import org.jboss.seam.annotations.datamodel.DataModel;
  | 
  | @Entity
  | @Name("foo")
  | @Table(name="FOOS")
  | public class Foo implements Serializable {
  |     
  |     private long   id;
  |     private String name;
  |     private Set<Bar> bars = new HashSet<Bar>();
  |     
  |     @Id
  |     @Column(name="FOO_ID")
  |     @GeneratedValue
  |     public Long getId() {
  |         return id;
  |     }
  |     public void setId(Long id) {
  |         this.id = id;
  |     }
  | 
  |     @Column(name="NAME")
  |     public String getName() {
  |         return name;
  |     }
  |     public void setName(String groupname) {
  |         this.name = groupname;
  |     }
  |     
  |     @ManyToMany(cascade=CascadeType.PERSIST)
  |     @JoinTable(name="FOO_BAR",
  |                [EMAIL PROTECTED](name="FOO_ID")},
  |                [EMAIL PROTECTED](name="BAR_ID")}) 
  |     public Set<Bar> getBars() {
  |         return bars;
  |     }
  |     public void setBars( Set<Bar> bars ) {
  |         this.bars = bars;
  |     }
  |     
  |     @Transient
  |     @DataModel(value="barList")
  |     public List<Bar> getBarList() {
  |         return new ArrayList<Bar>( bars );
  |     }
  |     
  |     @Override
  |     public String toString() {
  |         return "Foo[" + name + "]";
  |     }
  |     
  | }
  | 
  | 


Bar.java:


  | package com.orgmob.play;
  | 
  | import java.io.Serializable;
  | import java.util.HashSet;
  | import java.util.Set;
  | 
  | import javax.persistence.CascadeType;
  | import javax.persistence.Column;
  | import javax.persistence.Entity;
  | import javax.persistence.GeneratedValue;
  | import javax.persistence.Id;
  | import javax.persistence.ManyToMany;
  | import javax.persistence.Table;
  | 
  | import org.jboss.seam.annotations.Name;
  | 
  | @Entity
  | @Name("bar")
  | @Table(name="BARS")
  | public class Bar implements Serializable {
  |     
  |     private long   id;
  |     private String name;
  |     private Set<Foo> foos = new HashSet<Foo>();
  |     
  |     @Id
  |     @Column(name="BAR_ID")
  |     @GeneratedValue
  |     public Long getId() {
  |         return id;
  |     }
  |     public void setId(Long id) {
  |         this.id = id;
  |     }
  | 
  |     @Column(name="NAME")
  |     public String getName() {
  |         return name;
  |     }
  |     public void setName(String groupname) {
  |         this.name = groupname;
  |     }
  |     
  |     @ManyToMany(cascade=CascadeType.PERSIST,mappedBy="bars") 
  |     public Set<Foo> getFoos() {
  |         return foos;
  |     }
  |     public void setFoos( Set<Foo> foos ) {
  |         this.foos = foos;
  |     }
  |     
  |     @Override
  |     public String toString() {
  |         return "Bar[" + name + "]";
  |     }
  |    
  | }
  | 
  | 


FubarManager.java:


  | package com.orgmob.play;
  | 
  | import javax.ejb.Local;
  | 
  | @Local
  | public interface FubarManager {
  |     public void find();
  |     public void stop();
  |     public void createFoo();
  |     public void commitFoo();
  |     public void commitBar();
  |     public void destroy();
  |     public void delete();
  | }


FubarManagerBean.java:


  | package com.orgmob.play;
  | 
  | import java.io.Serializable;
  | import java.util.HashSet;
  | import java.util.List;
  | 
  | import javax.ejb.Remove;
  | import javax.ejb.Stateful;
  | import javax.persistence.EntityManager;
  | 
  | import org.jboss.seam.annotations.Begin;
  | import org.jboss.seam.annotations.Destroy;
  | import org.jboss.seam.annotations.End;
  | 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.log.Log;
  | 
  | @Stateful
  | @Name("fubarManager")
  | public class FubarManagerBean implements FubarManager, Serializable {
  |     
  |     @Logger 
  |     private Log log;
  |     
  |     @DataModel(value="fooList")
  |     private List<Foo> fooList;
  |     
  |     @DataModelSelection(value="fooList")
  |     @Out(required=false)
  |     private Foo foo;
  |     
  |     @DataModelSelection(value="barList")
  |     @Out(required=false)
  |     private Bar bar;
  |     
  |     @In(create=true)
  |     private EntityManager orgmobDatabase;
  |     
  |     @Begin(join=true)
  |     @Factory("fooList")
  |     public void find() {
  |         log.debug("looking for foo objects...");
  |         fooList = (List<Foo>)orgmobDatabase.createQuery(
  |                 "from Foo foo order by foo.id asc").getResultList();
  |         log.debug("found "+fooList.size()+" foos in fooList: " + fooList );
  |     }
  |     
  |     @End
  |     public void stop() {
  |     }
  |     
  |     private String newFooname() {
  |         // find a group name not currently seen by user;
  |         HashSet<String> foonameS = new HashSet<String>();
  |         for ( Foo foo : fooList ) {
  |             foonameS.add( foo.getName() );
  |         }
  |         String foonamePrefix = "foo";
  |         String fooname;
  |         int attempt = 1;
  |         do {
  |             fooname = foonamePrefix + (attempt++);
  |         } while ( foonameS.contains( fooname ) );
  |         return fooname;
  |     }
  |     
  |     public void createFoo() {
  |         
  |         foo = new Foo();
  |         foo.setName( newFooname() );
  |         orgmobDatabase.persist( foo );
  |         // always use the Bar with the lowest id.
  |         List<Bar> allBars = (List<Bar>)orgmobDatabase.createQuery(
  |                 "from Bar bar order by bar.id asc").getResultList();
  |         Bar bar = null;
  |         if ( allBars.size() > 0 ) {
  |             bar = allBars.get( 0 );
  |             // Foo owns the bidirectional many-to-many relationship with 
Bar.
  |             foo.getBars().add( bar );
  |         }
  |         orgmobDatabase.merge( foo );
  |         orgmobDatabase.flush();
  |         if ( null != bar ) {
  |             orgmobDatabase.refresh( bar );
  |         }
  |         
  |         log.debug( "for bar "+bar+" created foo: "+foo);
  |         log.debug( "foo "+foo+" has "+foo.getBars().size()+" bars");
  |         log.debug( "bar "+bar+" has "+bar.getFoos().size()+" foos");
  |         for ( Bar b : foo.getBars() ) {
  |             log.debug( "a bar for foo "+foo+": "+b);
  |         }
  |         if ( null != bar ) {
  |             for ( Foo f : bar.getFoos() ) {
  |                 log.debug( "a foo for bar"+bar+": "+f);
  |             }
  |         }
  |         
  |         find(); // update fooList
  |     }
  |     
  |     public void commitFoo() {
  |         if ( null == foo ) {
  |             log.error("FubarManagerBean.commitFoo() called but foo is 
null!");
  |         }
  |         else {
  |             orgmobDatabase.merge( foo );
  |         }
  |     }
  |     
  |     public void commitBar() {
  |         if ( null == bar ) {
  |             log.error("FubarManagerBean.commitBar() called but bar is 
null!");
  |         }
  |         else {
  |             orgmobDatabase.merge( bar );
  |         }
  |     }
  |     
  |     public void delete() {
  |         foo.getBars().remove(bar);
  |         orgmobDatabase.remove(bar);
  |         bar=null;
  |     }
  |     
  |     @Destroy @Remove
  |     public void destroy() {
  |     }
  | 
  | }
  | 

fubar.xhtml:


  | <!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:f="http://java.sun.com/jsf/core";
  |     xmlns:h="http://java.sun.com/jsf/html";
  |     xmlns:s="http://jboss.com/products/seam/taglib";
  |     xmlns:ui="http://java.sun.com/jsf/facelets";
  |     >
  |     <head>
  |             <meta http-equiv="Content-Type" content="text/html; 
charset=iso-8859-1" />
  |             <title>Fubar Manager</title>
  |     </head>
  |     <body>
  |             <h:form>
  |                     <h:outputText value="you have no foos"
  |                             rendered="#{empty fooList or fooList.rowCount 
== 0}" />
  |                     <ui:repeat  var="foo" value="#{fooList}" 
  |                             rendered="#{not empty fooList and 
fooList.rowCount > 0}">
  |                             <hr/>
  |                             <h:outputText value="#{1+fooList.rowIndex}"/>.
  |                             <s:link linkStyle="button" value="rename foo" 
action="#{fubarManager.commitFoo}" />
  |                             <h:inputText value="#{foo.name}" />
  |                             <br/>
  |                             <ui:repeat var="bar" value="#{foo.barList}">
  |                                     <br/>
  |                                     <s:link linkStyle="button" 
value="rename bar" action="#{fubarManager.commitBar}" />
  |                                     <h:inputText value="#{bar.name}" />
  |                             </ui:repeat>
  |                     </ui:repeat>
  |                     <hr/>
  |                     <hr/>
  |                     <s:link value="New Foo" 
action="#{fubarManager.createFoo}" linkStyle="button" />
  |             </h:form>
  |     </body>
  | </html>


components.xml:


  | <components>
  |     <component name="org.jboss.seam.core.init">
  |         <property name="myFacesLifecycleBug">true</property>
  |         <property name="jndiPattern">member/#{ejbName}/local</property>
  |     </component>
  |     <component class="org.jboss.seam.core.Ejb" 
  |            installed="false"/>
  |     <!-- Configuring a managed persistence context -->
  |     <component name="orgmobDatabase"
  |             class="org.jboss.seam.core.ManagedPersistenceContext">
  |             <property 
name="persistenceUnitJndiName">java:/EntityManagerFactories/orgmobData</property>
  |     </component>
  | </components>

import.sql:


  | insert into FOOS(FOO_ID,NAME) values (1,'foo1')
  | insert into FOOS(FOO_ID,NAME) values (2,'foo2')
  | insert into FOOS(FOO_ID,NAME) values (3,'foo3')
  | insert into FOOS(FOO_ID,NAME) values (4,'foo4')
  | insert into FOOS(FOO_ID,NAME) values (5,'foo5')
  | 
  | insert into BARS(BAR_ID,NAME) values(1,'bar1')
  | insert into BARS(BAR_ID,NAME) values(2,'bar2')
  | insert into BARS(BAR_ID,NAME) values(3,'bar3')
  | insert into BARS(BAR_ID,NAME) values(4,'bar4')
  | insert into BARS(BAR_ID,NAME) values(5,'bar5')
  | 
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(1,1)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(2,2)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(1,2)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(3,3)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(1,3)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(4,4)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(1,4)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(5,5)
  | insert into FOO_BAR(FOO_ID,BAR_ID) values(1,5)
  | 


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

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3961165
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to