[jboss-user] [JBoss Seam] - Re: Seam - iterator tag?

dbatcn do-not-reply at jboss.com
Wed Jul 26 20:25:50 EDT 2006


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",
  |                joinColumns={@JoinColumn(name="FOO_ID")},
  |                inverseJoinColumns={@JoinColumn(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



More information about the jboss-user mailing list