10 Replies Latest reply on Nov 17, 2006 1:50 AM by kanth_seenu

    Value object use

    homer

      Hi,

      I want to use value objects.

      I read the xdoclet documention about value object, but when I try to use the xdoclet @ejb.value-object tag, I get an exception :

      13:27:32,103 ERROR [LogInterceptor] TransactionRolledbackLocalException in method: public abstract fr.edumedia.value.parameter.LanguageValue fr.edumedia.interfaces.entity.parameter.LanguageLocal.getLanguageValue(), causedBy:
      javax.ejb.EJBException: Method is not a known CMP field accessor, CMR field accessor, or ejbSelect method: methodName=getLanguageValue
       at org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler.invoke(EntityBridgeInvocationHandler.java:106)
       at org.jboss.proxy.compiler.Runtime.invoke(Runtime.java:59)
       at fr.edumedia.ejb.entity.parameter.LanguageBean$Proxy.getLanguageValue(<generated>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
       at java.lang.reflect.Method.invoke(Unknown Source)
       at org.jboss.ejb.EntityContainer$ContainerInterceptor.invoke(EntityContainer.java:1096)
       at org.jboss.ejb.plugins.cmp.jdbc.JDBCRelationInterceptor.invoke(JDBCRelationInterceptor.java:72)
       at org.jboss.ejb.plugins.EntitySynchronizationInterceptor.invoke(EntitySynchronizationInterceptor.java:282)
       at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
       at org.jboss.ejb.plugins.EntityReentranceInterceptor.invoke(EntityReentranceInterceptor.java:114)
       at org.jboss.ejb.plugins.EntityInstanceInterceptor.invoke(EntityInstanceInterceptor.java:163)
       at org.jboss.ejb.plugins.EntityLockInterceptor.invoke(EntityLockInterceptor.java:89)
       at org.jboss.ejb.plugins.EntityCreationInterceptor.invoke(EntityCreationInterceptor.java:54)
       at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
       at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267)
       at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
       at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118)
       at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
       at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
       at org.jboss.ejb.EntityContainer.internalInvoke(EntityContainer.java:489)
       at org.jboss.ejb.Container.invoke(Container.java:700)
       at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invoke(BaseLocalProxyFactory.java:375)
       at org.jboss.ejb.plugins.local.EntityProxy.invoke(EntityProxy.java:38)
       at $Proxy348.getLanguageValue(Unknown Source)
       at fr.edumedia.ejb.session.ParameterManagerBean.createLanguage(ParameterManagerBean.java:180)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
       at java.lang.reflect.Method.invoke(Unknown Source)
       at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:683)
       at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
       at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:72)
       at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
       at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267)
       at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
       at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118)
       at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
       at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
       at org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionContainer.java:331)
       at org.jboss.ejb.Container.invoke(Container.java:700)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
       at java.lang.reflect.Method.invoke(Unknown Source)
       at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
       at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:101)
       at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:90)
       at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
       at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
       at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:100)
       at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
       at $Proxy360.createLanguage(Unknown Source)
       at fr.edumedia.struts.action.TestEJB.execute(TestEJB.java:35)
       at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
       at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
       at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
       at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
       at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
       at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
       at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:220)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.jboss.web.tomcat.tc4.statistics.ContainerStatsValve.invoke(ContainerStatsValve.java:76)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
       at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
       at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2417)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
       at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:65)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:577)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641)
       at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
       at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
       at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643)
       at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
       at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
       at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:197)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:781)
       at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:549)
       at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
       at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
       at java.lang.Thread.run(Unknown Source)
      
      


      My Language EJB looks like :

      /**
       * @ejb.bean cmp-version = "2.x"
       * name = "Language"
       * primkey-field = "id"
       * view-type = "local"
       * type = "CMP"
       *
       * @ejb.ejb-ref ejb-name = "Label"
       * view-type = "local"
       *
       * @ejb.persistence table-name = "language"
       * @jboss.persistence create-table = "true"
       * pk-constraint = "no"
       * table-name = "language"
       *
       * @ejb.util generate = "physical"
       * @ejb.value-object match = "*"
       *
       */
      public abstract class LanguageBean implements EntityBean {
      
       private EntityContext _ctx;
      
       //#######################################
      
       /**
       * @ejb.interface-method
       *
       * @jboss.persistence auto-increment = "true"
       * @ejb.persistence column-name = "id"
       */
       public abstract Integer getId();
       /**
       * @ejb.interface-method
       */
       public abstract void setId(Integer newLanguageId);
      
       /**
       * @ejb.interface-method
       * @ejb.value-object compose = "fr.edumedia.value.parameter.LabelValue"
       * compose-name = "Label"
       * members = "fr.edumedia.interfaces.entity.parameter.LabelLocal"
       * members-name = "Label"
       * @ejb.relation name = "Language-Label"
       * role-name = "Language-has-Label"
       * target-ejb = "Label"
       * target-role-name = "Label-of-Language"
       * target-cascade-delete = "true"
       * @jboss.relation fk-column = "labelid"
       * related-pk-field = "id"
       * fk-constraint = "true"
       */
       public abstract LabelLocal getLabel();
       /**
       * @ejb.interface-method
       */
       public abstract void setLabel(LabelLocal newLanguageLabel);
      
       // #######################################
      
       /**
       * @ejb.interface-method
       */
       public abstract LanguageValue getLanguageValue();
       /**
       * @ejb.interface-method
       */
       public abstract void setLanguageValue(LanguageValue language);
      
      ...


      Note the two last methods, the first may return me the value object for this entity EJB, but it appears that NO!!!

      Can anybody help me and tell me where I can get a better documentation about the value-object xdoclet tag use.

      Thanks.

        • 1. Re: Value object use
          sesques

          Hi,

          Your error got nothing to do with value objects.
          The error says that the getLanguageValue method do not correspond to a CMP or a CMR field, which is the case in your code.

          Your getter end setter for languageValue must be defined as a relation between your bean and the "LanguageValue" bean.

          Pascal

          • 2. Re: Value object use
            homer

            Thanks for your reply,

            Your getter end setter for languageValue must be defined as a relation between your bean and the "LanguageValue" bean


            I don't want to have a relation between Language (Bean) and LanguageValue(Value Object of the Language bean), just get the value object representation of my Language bean, as in the xdoclet documentation (http://xdoclet.sourceforge.net/valueobjects.html) where the customer bean have an abstract method (getCustomerValue()) which retrieve the value object of the customer bean. I have to do something in ejbCreate or ejbPostCreate in order to initialize the value object ?

            Have you a concrete example of the use of the value object with xdoclet, getting a value object of a bean.

            Thanks.

            • 3. Re: Value object use
              sesques

              Hi,

              I never use the value object pattern, and of course the Xdoclet tag.
              I can tell you that the error you get comes from the reason I give you.
              When I look at the code snippet given as example in SourceForge for the Value Object tag, I can see that each getter and setter pairs are defined as CMP or CMR fields.
              In your code, the languageValue is not a value object but a field which is undefined for the persistence manager. The value object you use concerns the LabelValue bean (label field).
              I cannot help you for value objects, but your implementation is not good.

              Pascal

              • 4. Re: Value object use
                homer

                I am not crazy ?!



                * @ejb.value-object
                 * name="Customer"
                 * match="*"
                 *
                 * @ejb.value-object
                 * name="CustomerLight"
                 * match="light"
                 */
                public abstract class CustomerEJB implements EntityBean {
                
                ...
                
                /**
                 * @ejb.interface-method
                 */
                 public abstract CustomerValue getCustomerValue();
                
                 /**
                 * @ejb.interface-method
                 */
                 public abstract CustomerLightValue getCustomerLightValue();
                
                 /**
                 * @ejb.interface-method
                 */
                 public abstract void setCustomerValue(CustomerValue value);


                This code snippet from xdoclet example doesn't imply any CMP(ejb.persistence ?) or CMR(ejb.relation ?) fields. And this example reflects exactly what I want : get the value object of the entity bean itself.

                When I look at the code snippet given as example in SourceForge for the Value Object tag, I can see that each getter and setter pairs are defined as CMP or CMR fields.


                Yes, for the persistent fields but not for the three last methods given before.

                The error says that the getLanguageValue method do not correspond to a CMP or a CMR field, which is the case in your code.


                I know the signification of the exception but regarding the xdoclet example I have just to define this abstract methods.

                I never use the value object pattern, and of course the Xdoclet tag.


                If you don't use value object, how do you get the values of your entity beans in your views(JSP, etc...) ?

                Thanks.



                • 5. Re: Value object use
                  sesques

                  No you are not crazy, sorry. I looked very fast the example (1s) and I read @ejb.persistent-field everywhere (optical effect).

                  So, the error says that nothing was generated by XDoclet (My understanding is that the value object tag will generate extra classes). Do you define a valueobject tag in the Xdoclet build file ? I use myself JBoss IDE and I can see a valueobject task in the list (XDoclet configuration).
                  Also, I see one difference with the example: you don't give the name of the value object.

                  If you don't use value object, how do you get the values of your entity beans in your views(JSP, etc...) ?


                  I use Struts for my views, so I encapsulate all my EJB's calls on a MBean component called by the action servlet.



                  • 6. Re: Value object use
                    dhartford

                    heya,
                    Try changing:

                    * @ejb.value-object match = "*"


                    to:

                    * @ejb.value-object
                     * name="Language"
                     * match = "*"




                    • 7. Re: Value object use
                      homer

                      Hi,

                      I have solved my problem. XDcolet is very powerful !!!

                      My code wasn't wrong, I just forgot to include the entitycmp subtask in the ejbdoclet. With this subtask, XDoclet will generate one class, which extends the entitybean, for each entitybean. This classes include implementation of the life cycle methods (ejbStore, ejbLoad etc..., which can be empty if they were empty in entitybean or just call super.ejbXXX() if they were no no-op in entitybean), and if the @ejb.value-object tag is present in the entitybean, this classes will include methods like :

                      public LanguageValue getLanguageValue(){ ...}


                      But in order to they appear in the local and/or remote interface, we have to define these methods abstract in the entitybean with the @ejb.interface-method tag :

                      /**
                       * @ejb.interface-method
                       **/
                      
                      public abstract LanguageValue getLanguageValue();


                      And finally, XDoclet generate ejb-jar.xml with the ejb-class tags with the concrete classes and not with entitybean.

                      For example, my previou example looks like :

                      My Language Entity Bean :
                      /**
                       *
                       * @ejb.bean cmp-version = "2.x"
                       * name = "Language"
                       * primkey-field = "id"
                       * view-type = "local"
                       * type = "CMP"
                       *
                       * @ejb.persistence table-name = "language"
                       * @jboss.persistence create-table = "true"
                       * pk-constraint = "no"
                       * table-name = "language"
                       *
                       * @ejb.util generate = "physical"
                       * @ejb.value-object
                       *
                       */
                      public abstract class LanguageBean implements EntityBean {
                      ...
                      
                      /**
                       * @ejb.interface-method
                       */
                       public abstract LanguageValue getLanguageValue();
                      
                       // #######################################
                      
                       /* (non-Javadoc)
                       * @see javax.ejb.EntityBean#setEntityContext(javax.ejb.EntityContext)
                       */
                       public void setEntityContext(EntityContext ctx)
                       throws EJBException, RemoteException {
                       this._ctx = ctx;
                       }
                      
                       /* (non-Javadoc)
                       * @see javax.ejb.EntityBean#unsetEntityContext()
                       */
                       public void unsetEntityContext() throws EJBException, RemoteException {
                       this._ctx = null;
                       }
                      
                       /**
                       * @ejb.create-method
                       */
                       public Integer ejbCreate(String label)throws javax.ejb.CreateException{
                       this.setLabel(label);
                       return null;
                       }
                      
                       public void ejbPostCreate(String label) {
                       }
                      }


                      The auto generated concrete class :

                      /*
                       * Generated by XDoclet - Do not edit!
                       */
                      package fr.edumedia.ejb.entity.parameter;
                      
                      /**
                       * CMP layer for Language.
                       */
                      public abstract class LanguageCMP
                       extends fr.edumedia.ejb.entity.parameter.LanguageBean
                       implements javax.ejb.EntityBean
                      {
                      
                       public void ejbLoad()
                       {
                       }
                      
                       public void ejbStore()
                       {
                       }
                      
                       public void ejbActivate()
                       {
                       }
                      
                       public void ejbPassivate()
                       {
                      
                       LanguageValue = null;
                       }
                      
                       public void setEntityContext(javax.ejb.EntityContext ctx) throws javax.ejb.EJBException, java.rmi.RemoteException
                       {
                       super.setEntityContext(ctx);
                       }
                      
                       public void unsetEntityContext() throws javax.ejb.EJBException, java.rmi.RemoteException
                       {
                       super.unsetEntityContext();
                       }
                      
                       public void ejbRemove() throws javax.ejb.RemoveException
                       {
                      
                       }
                      
                       /* Value Objects BEGIN */
                      
                       private fr.edumedia.value.parameter.LanguageValue LanguageValue = null;
                      
                       public fr.edumedia.value.parameter.LanguageValue getLanguageValue()
                       {
                       LanguageValue = new fr.edumedia.value.parameter.LanguageValue();
                       try
                       {
                       LanguageValue.setId( getId() );
                       LanguageValue.setLabel( getLabel() );
                      
                       }
                       catch (Exception e)
                       {
                       throw new javax.ejb.EJBException(e);
                       }
                      
                       return LanguageValue;
                       }
                      
                      /* Value Objects END */
                      
                       public abstract java.lang.Integer getId() ;
                      
                       public abstract void setId( java.lang.Integer id ) ;
                      
                       public abstract java.lang.String getLabel() ;
                      
                       public abstract void setLabel( java.lang.String label ) ;
                      
                      }
                      


                      And the ejb-jar.xml :
                      <entity >
                       <description>[CDATA[]]</description>
                      
                       <ejb-name>Language</ejb-name>
                      
                       <local-home>fr.edumedia.interfaces.entity.parameter.LanguageLocalHome</local-home>
                       <local>fr.edumedia.interfaces.entity.parameter.LanguageLocal</local>
                      
                       <ejb-class>fr.edumedia.ejb.entity.parameter.LanguageCMP</ejb-class>
                       <persistence-type>Container</persistence-type>
                       <prim-key-class>java.lang.Integer</prim-key-class>
                       <reentrant>False</reentrant>
                       <cmp-version>2.x</cmp-version>
                       <abstract-schema-name>Language</abstract-schema-name>
                       <cmp-field >
                       <description>[CDATA[]]</description>
                       <field-name>id</field-name>
                       </cmp-field>
                       <cmp-field >
                       <description>[CDATA[]]</description>
                       <field-name>label</field-name>
                       </cmp-field>
                       <primkey-field>id</primkey-field>
                      
                       <!-- Write a file named ejb-finders-LanguageBean.xml if you want to define extra finders. -->
                       </entity>


                      I hope that this will help somebody to avoid boring works!!!

                      To resume, with XDoclet, entityCMP and value-objects, we can :

                      - avoid to implement no-op life cycle methods which will be implemented in concrete classes,
                      - get value objects, which avoid network calls for each method calls , for use in views,
                      - all is generated automatically, except for the definition of the abstract methods in entity bean.

                      But, I have a problem with the value objects : they don't like cyclic references. I'am trying to solve this.

                      • 8. Re: Value object use
                        kanth_seenu

                        Hi Homer / Anyone,

                        I need your help in understanding

                        " I just forgot to include the entitycmp subtask in the ejbdoclet"

                        I am struck at the same place where you are at the begining of this post.

                        • 9. Re: Value object use
                          kanth_seenu

                          I found it I was missing in my build file

                          Umakanth Srinivasan

                          • 10. Re: Value object use
                            kanth_seenu

                            I found it I was missing dataobject tag in my build file

                            Umakanth Srinivasan