1 2 3 Previous Next 34 Replies Latest reply on Jun 30, 2006 12:00 PM by supernovasoftware.com Go to original post
      • 15. Re: whew! finally, a pattern for SelectItems using generics
        patrick_ibg

        Try this fix to getAsString:

        public String getAsString (FacesContext context, UIComponent component, Object object)
        {
         if (object == null)
         return null ;
        
         if (!(object instanceof Lookup))
         return null ;
        
         T lookup = (T) object ;
         return lookup.getKey () ;
        }
        


        • 16. Re: whew! finally, a pattern for SelectItems using generics

          Sorry the same error :-(

          • 17. Re: whew! finally, a pattern for SelectItems using generics
            drapierwim

            Work great, thanks a lost but since i'm a newbie could you tell me what
            the pro and cons are for this approach?

            I also found a typo, instead of the state names it renders the id in the jsp


            // add selectItemList
            List<SelectItem> selectItemList = new ArrayList<SelectItem> () ;
            for (T entity : entityList) {
            Lookup l = (Lookup) entity ;
            SelectItem item = new SelectItem (entity, l.getKey(), l.getName()) ;
            selectItemList.add (item) ;
            }
            selectItemListMap.put (entityClass, selectItemList) ;
            }

            here is what it should bet

            SelectItem item = new SelectItem (entity, l.getName(), l.getKey()) ;
            


            • 18. Re: whew! finally, a pattern for SelectItems using generics
              patrick_ibg

              You're right about the "typo", it comes from my misunderstanding on how the SelectItem object is used. It turns out, the third parameter is for use by an IDE. More likely, it should be like this:

              SelectItem item = new SelectItem (entity, l.getName(), l.getName()) ;

              As for the pros/cons, well, it's just a pattern that works well with the Generic DAO pattern. I'm actually moving away from the Generic DAO pattern and using something like a base DAO for all entities, then a subclassed DAO per package. This somewhat simplifies the aforementioned SelectItems pattern. I'll post the new code once its finished...

              • 19. Re: whew! finally, a pattern for SelectItems using generics
                lavoir

                Patrick,

                I get the feeling that the post by Gavin about the @Factory discussion might attempt to solve a similar problem then the one discussed here.

                ref:
                http://www.jboss.com/index.html?module=bb&op=viewtopic&t=72267

                I m also curious as to why you decided to move away from the Generic DAO pattern.

                I was in fact starting a small project testing out, uhm ... well pretty much all you posted so far :)


                • 20. Re: whew! finally, a pattern for SelectItems using generics
                  drapierwim

                  I use the eclipse IDE and get some type safety warnings that I don't understand well, can somebody explain this warning from the SelectItems class a bit.

                  Type safety: The cast from Map<String,capture-of ? extends Lookup> to Map<String,T> is actually checking against the erased type Map


                  • 21. Re: whew! finally, a pattern for SelectItems using generics
                    patrick_ibg

                     

                    "lavoir" wrote:

                    I get the feeling that the post by Gavin about the @Factory discussion might attempt to solve a similar problem then the one discussed here.


                    The @Factory annotation should help to instantiate a SelectItems when you don't already have one. However, you'd still need the code to create the list of SelectItems in your Action bean. In the case of a global drop-down such as a list of States, you might want to keep it in the Application Context for all pages/actions to access, in which case the original pattern still applies.

                    "lavoir" wrote:

                    I m also curious as to why you decided to move away from the Generic DAO pattern.


                    The Generic DAO pattern requires that you have a DAO class per entity class, and an interface per DAO. So for each entity, that's two additional java files that may not necessarily have any methods specific to that entity. Consider the following:

                    @EmbeddableSuperclass (AccessType.FIELD)
                    public class BaseEntity
                     implements Serializable {
                     // my root persistent class
                     @Id
                     private Long id ;
                     private Date createDate ;
                     // etc...
                     public Long getId () {...}
                     public void setId (Long id) { ... }
                     public Date getCreateDate () ... etc. etc...
                    }
                    
                    @Entity (AccessType.FIELD)
                    public class Account extends BaseEntity
                     implements Serializable {
                     private String userName ;
                     private String password ;
                     private String email ;
                     ...
                    }
                    
                    @Entity ...
                    public class CustomerAccount extends Account
                     implements Serializable {
                    
                     private Address shipAddress ;
                     private Address billAddress ;
                     ...
                    }
                    
                    @Entity ...
                    public class AdminAccount extends Account
                     implements Serializable {
                     @OneToMany
                     private List<Role> roles ;
                    }
                    


                    Would require the following:

                    public abstract class GenericDaoBean<T extends BaseEntity>
                     implements GenericDao<T>
                    {
                     @PersistenceContext EntityManager em ;
                    
                     protected Class<T> persistentClass ;
                    
                     protected GenericDaoBean (Class<T> persistentClass) {
                     this.persistentClass = persistentClass ;
                     }
                    
                     public T find (Long id) {
                     return em.find (persistentClass, id) ;
                     }
                    
                     public T merge (T entity) { ... }
                     public List<T> list () { ... }
                     // etc...
                    }
                    
                    public interface GenericDao<T extends BaseEntity> {
                     public T find (Long id) ;
                     public T merge (T entity) ;
                     public List<T> list () ;
                    }
                    
                    public interface AccountDao<T extends Account>
                     extends GenericDao<T>
                    {
                     public T login (String userName, String password) ;
                    }
                    
                    public abstract class AccountDaoBean<T extends Account>
                     extends GenericDao<T>
                     implements AccountDao<T>
                    {
                     protected AccountDaoBean (Class<T> clazz) {
                     super (clazz) ;
                     }
                     public T login (String userName, String password) { ... }
                    }
                    
                    public interface CustomerAccountDao
                     extends AccountDao<CustomerAccount>
                    {
                     // no methods
                    }
                    
                    public class CustomerAccountDaoBean
                     extends AccountDaoBean<CustomerAccount>
                     implements CustomerAccountDao
                    {
                     public CustomerAccountDaoBean () {
                     super (CustomerAccount.class) ;
                     }
                     // no other methods
                    }
                    
                    public interface AdminAccountDao
                     extends AccountDao<AdminAccount>
                    {
                     // no methods
                    }
                    
                    public class AdminAccountDaoBean
                     extends AccountDaoBean<AdminAccount>
                     implements AdminAccountDao
                    {
                     public AdminAccountDaoBean () {
                     super (AdminAccount.class) ;
                     }
                     // no other methods
                    }
                    


                    You get the point... I started with my code laid out this way and decided it was too cumbersome to add DaoBean and interface classes for Entities that just needed the basic find/merge/etc operations...

                    Not to say that the Generic DAO pattern is bad... I think it's useful in situations where you want to create strong layering, like when you think your persistence solution might change faster than and independent of your business layer. It's also good if you have several developers that can each work on their own layer without stepping on one another's toes.

                    In my particular situation, where I am responsible for developing the persistence layer, the business layer AND the presentation layer, and it's all server-side and web-based, the cons of using the Generic DAO pattern outweigh the pros.


                    • 22. Re: whew! finally, a pattern for SelectItems using generics

                      Hi All

                      I have created the stateconverter as per this discussion thread (in the war), all my seam managed objects are within the ejb file. I have registered the converter in the faces-config.xml. Both the ejb3 and war are packaged within an ear package.

                      When I try to post the web page (so perform conversion), I get this error:

                      javax.servlet.ServletException: java.lang.ClassNotFoundException: No ClassLoaders found for: uk.com.millwood.View.Converters.SiteConverter
                       javax.faces.webapp.FacesServlet.service(FacesServlet.java:121)
                       org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:123)
                       org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
                      
                      root cause
                      
                      javax.faces.FacesException: java.lang.ClassNotFoundException: No ClassLoaders found for: uk.com.millwood.View.Converters.SiteConverter
                       org.apache.myfaces.util.StateUtils.getAsObject(StateUtils.java:276)
                       org.apache.myfaces.util.StateUtils.reconstruct(StateUtils.java:214)
                       org.apache.myfaces.renderkit.html.HtmlResponseStateManager.getComponentStateToRestore(HtmlResponseStateManager.java:220)
                       org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:129)
                       org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:219)
                       org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:255)
                       org.apache.myfaces.lifecycle.LifecycleImpl.restoreView(LifecycleImpl.java:144)
                       org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:67)
                       javax.faces.webapp.FacesServlet.service(FacesServlet.java:106)
                       org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:123)
                       org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
                      


                      I've looked at the deployed application and the classes are in WEB-INF/classes folder. The web app picks up messages.properties (also stored in the wars WEB-INF/classes folder.

                      Did the original person answering this thread deploy seperately to a ejb3 war, or did they get round this by putting all in the war file.

                      Many thanks for nay comments.

                      James

                      • 23. Re: whew! finally, a pattern for SelectItems using generics
                        gavin.king

                        It's just a classpath issue....

                        • 24. Re: whew! finally, a pattern for SelectItems using generics
                          drapierwim

                          I'm trying to implement the generic DAO pattern. so @patrick_ibg could you post this more in detail.

                          For the moment i'm having problems loading the entities i've got the following error

                          23:14:34,654 INFO [SelectItems] Initializing SelectItems
                          23:16:25,694 INFO [STDOUT] 14-dec-2005 23:16:25 com.sun.facelets.FaceletViewHandler handleRenderException
                          SEVERE: Error Rendering View
                          java.lang.IllegalStateException: No transaction.
                           at org.jboss.tm.TxManager.setRollbackOnly(TxManager.java:381)
                           at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.setRollbackOnly(ServerVMClientUserTransaction.java:141)
                           at org.jboss.seam.interceptors.RollbackInterceptor.rollbackIfNecessary(RollbackInterceptor.java:55)
                           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                           at java.lang.reflect.Method.invoke(Method.java:585)
                           at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                           at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:81)
                           at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:66)
                           at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:32)
                           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                           at java.lang.reflect.Method.invoke(Method.java:585)
                           at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                           at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:81)
                           at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:66)
                           at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:46)
                           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                           at java.lang.reflect.Method.invoke(Method.java:585)
                           at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                           at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:81)
                           at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:66)
                           at org.jboss.seam.interceptors.BusinessProcessInterceptor.manageBusinessProcessContext(BusinessProcessInterceptor.java:58)
                           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                           at java.lang.reflect.Method.invoke(Method.java:585)
                           at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                           at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:81)
                           at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:66)
                           at org.jboss.seam.interceptors.RemoveInterceptor.removeIfNecessary(RemoveInterceptor.java:31)
                           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                           at java.lang.reflect.Method.invoke(Method.java:585)
                           at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                           at org.jboss.seam.interceptors.Interceptor.aroundInvoke(Interceptor.java:81)
                           at org.jboss.seam.interceptors.SeamInvocationContext.proceed(SeamInvocationContext.java:66)
                           at org.jboss.seam.ejb.SeamInterceptor.aroundInvoke(SeamInterceptor.java:41)
                           at org.jboss.seam.interceptors.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:52)
                           at org.jboss.seam.interceptors.JavaBeanInterceptor.intercept(JavaBeanInterceptor.java:40)
                           at ivvo.drapier.seam.SelectItems$$EnhancerByCGLIB$$20e0a7fb.create(<generated>)
                           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                           at java.lang.reflect.Method.invoke(Method.java:585)
                           at org.jboss.seam.util.Reflections.invoke(Reflections.java:13)
                           at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:32)
                           at org.jboss.seam.Component.callComponentMethod(Component.java:967)
                           at org.jboss.seam.Component.callCreateMethod(Component.java:955)
                           at org.jboss.seam.Component.newInstance(Component.java:944)
                           at org.jboss.seam.Component.getInstance(Component.java:892)
                           at org.jboss.seam.jsf.SeamVariableResolver.resolveVariable(SeamVariableResolver.java:43)
                           at com.sun.facelets.el.LegacyELContext$LegacyELResolver.getValue(LegacyELContext.java:130)
                           at com.sun.el.parser.AstIdentifier.getValue(AstIdentifier.java:41)
                           at com.sun.el.parser.AstValue.getValue(AstValue.java:85)
                           at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:183)
                           at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
                           at com.sun.facelets.el.LegacyValueBinding.getValue(LegacyValueBinding.java:56)
                           at javax.faces.component.UISelectItems.getValue(UISelectItems.java:55)
                           at org.apache.myfaces.util.SelectItemsIterator.hasNext(SelectItemsIterator.java:103)
                           at org.apache.myfaces.renderkit.RendererUtils.internalGetSelectItemList(RendererUtils.java:485)
                           at org.apache.myfaces.renderkit.RendererUtils.getSelectItemList(RendererUtils.java:461)
                           at org.apache.myfaces.renderkit.html.HtmlRendererUtils.internalRenderSelect(HtmlRendererUtils.java:272)
                           at org.apache.myfaces.renderkit.html.HtmlRendererUtils.renderMenu(HtmlRendererUtils.java:246)
                           at org.apache.myfaces.renderkit.html.HtmlMenuRendererBase.encodeEnd(HtmlMenuRendererBase.java:54)
                           at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:331)
                           at com.sun.facelets.FaceletViewHandler.encodeRecursive(FaceletViewHandler.java:521)
                           at com.sun.facelets.FaceletViewHandler.encodeRecursive(FaceletViewHandler.java:518)
                           at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:447)
                           at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:352)
                           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:107)
                           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
                           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                           at org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:122)
                           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                           at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
                           at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
                           at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
                           at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
                           at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
                           at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
                           at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
                           at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
                           at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
                           at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
                           at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
                           at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
                           at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
                           at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
                           at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
                           at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSla
                          23:16:25,734 INFO [STDOUT] veWorkerThread.java:112)
                           at java.lang.Thread.run(Thread.java:595)
                          23:16:25,734 INFO [STDOUT] 14-dec-2005 23:16:25 com.sun.facelets.FaceletViewHandler handleRenderException
                          SEVERE: Took Type: java.io.PrintWriter
                          


                          My quess is that the injection of the persistencecontext should occur in my
                          SLSB, for the moment it is injected in my superclass(class for CRUD) to access it i'm using a protected method in the superclass getEntityManager seen on the CaveatEmptor project, if so how can i deal with this problem

                          • 25. Re: whew! finally, a pattern for SelectItems using generics
                            patrick_ibg

                            Try adding some more logging into the SelectItems class.

                            Is your CRUD superclass an SLSB with an injected PersistenceContext?

                            • 26. Re: whew! finally, a pattern for SelectItems using generics

                              I just realized that a converter class can be specified by value binding. (I assume this is a JSF behavior and not just a MyFaces details) Here's an example from the non-seam DVD Store:

                              <h:selectOneMenu converter="#{catalog.converter}"
                               value="#{catalog.product.category}">
                               <f:selectItems value="#{catalog.categoryItems}" />
                              </h:selectOneMenu>
                              


                              Here, the converter instance is created by the catalog in the same scope as the categoryItems value, so it's easy to make use of that exact data set rather than some application-scoped data. (which only makes sense for select menus based on static application-scope data)

                              In Seam, this can obviously be easier because the converter itself could be a Seam component. We wouldn't need to couple the converter so closely with the app code. So, if you have a #{items} somewhere, you should be able to have a #{itemsConverter} which injects #{items} and converts from there.

                              Of course, I haven't yet tried this with Seam. As I said, I'm working with a pure EJB3 app today. I'll try and put this in the Seam DVD Store this weekend and see if there are any issues.



                              • 27. Re: whew! finally, a pattern for SelectItems using generics
                                armita

                                Is there a way to eliminate coding and registering one converter for every Lookup ?
                                And alo is there anyway to implicitly assign the converter in the view instead of using the converter in every element?

                                • 28. Re: whew! finally, a pattern for SelectItems using generics
                                  armita

                                  Oops, I coul not implement it. Sorry for newbie question, could any body please tell me whet exactly this onCreate method is called? I couldn't see the log messages anywhere.

                                  • 29. Re: whew! finally, a pattern for SelectItems using generics
                                    drapierwim

                                    I don't understand your question well, but the onCreate() gets called when the Seam component selectItems instance is created by making use of the @create annotation, if you can't see logging than maybe your selectItems is not a Seam component make sure you have an @name annotation.

                                    If not post your code, Cheers