inheritance with EJBs (CMP) also for find-methods supported?

Discussion in 'Java' started by Frank Ratzlow, Nov 9, 2003.

  1. Hi folks,

    I'm writing a short application and encounter problems with the
    declaration of find methods.
    My class looks a bit simplified (leaving all the interface, life
    cycle, xdoclet tags bla bla)

    public abstrac class Person {
    public abstract String getFirstname();
    public abstract void setFirstname(String firstname);

    public abstract String getLastname();
    public abstract void setLastname(String lastname);
    }


    public abstrac class Student extends Person {
    public abstract long getMatNo();
    public abstract void setMatNo(long MatNo);

    public abstract String getLastname();
    public abstract void setLastname(String lastname);
    }


    The person class is only created to serve as abstract class to derive
    from for specialized classes, so no table for it will be created in
    the database.
    I wonder why I can only query attributes in Student class that were
    directly declared there.
    How do I declare a finder method for one of it's inherited fields e.g.
    "lastname"?
    XDoclet generated for the Student class something like that:

    <query>
    <query-method>
    <method-name>findByLastname</method-name>
    <method-params>
    <method-param>String</method-param>
    </method-params>
    </query-method>
    <ejb-ql><![CDATA[SELECT OBJECT(s) FROM Student AS s WHERE s.lastname =
    ?1]]></ejb-ql>
    </query>

    This looks perfect to me but when deploying I get the following error
    message:

    Bean : Student
    Method : public abstract Collection findByLastname(String) throws
    FinderException, RemoteException
    Section: 10.5.6
    Warning: Every finder method except findByPrimaryKey(key) must be
    associated with a query element in the deployment descriptor.

    I would really appreciate if anyone could give me a hint, what's
    wrong. Is there something special to 'findXXX' and 'selectXXX'
    methods?

    TIA

    Frank


    JBoss 3.2, XDoclet 1.2b3, sdk 1.4.2 OS: Windows XP
    Frank Ratzlow, Nov 9, 2003
    #1
    1. Advertising

  2. Frank Ratzlow wrote:
    > I'm writing a short application and encounter problems with the
    > declaration of find methods.


    Have you checked the EJB spec? It's available free from Sun. I'm a bit
    out of my usual stomping grounds here, having not played much with CMP,
    but I do have the spec at hand so I'll offer a suggestion or two. (below)

    > My class looks a bit simplified (leaving all the interface, life
    > cycle, xdoclet tags bla bla)
    >
    > public abstrac class Person {
    > public abstract String getFirstname();
    > public abstract void setFirstname(String firstname);
    >
    > public abstract String getLastname();
    > public abstract void setLastname(String lastname);
    > }
    >
    >
    > public abstrac class Student extends Person {
    > public abstract long getMatNo();
    > public abstract void setMatNo(long MatNo);
    >
    > public abstract String getLastname();
    > public abstract void setLastname(String lastname);
    > }
    >
    >
    > The person class is only created to serve as abstract class to derive
    > from for specialized classes, so no table for it will be created in
    > the database.
    > I wonder why I can only query attributes in Student class that were
    > directly declared there.


    I suspect that you are mischaracterizing the problem. This might be,
    for instance, because your app server is doing more for you than J2EE
    requires, but less than is necessary to make everything work.

    > How do I declare a finder method for one of it's inherited fields e.g.
    > "lastname"?
    > XDoclet generated for the Student class something like that:
    >
    > <query>
    > <query-method>
    > <method-name>findByLastname</method-name>
    > <method-params>
    > <method-param>String</method-param>
    > </method-params>
    > </query-method>
    > <ejb-ql><![CDATA[SELECT OBJECT(s) FROM Student AS s WHERE s.lastname =
    > ?1]]></ejb-ql>
    > </query>
    >
    > This looks perfect to me but when deploying I get the following error
    > message:
    >
    > Bean : Student
    > Method : public abstract Collection findByLastname(String) throws
    > FinderException, RemoteException
    > Section: 10.5.6
    > Warning: Every finder method except findByPrimaryKey(key) must be
    > associated with a query element in the deployment descriptor.
    >
    > I would really appreciate if anyone could give me a hint, what's
    > wrong. Is there something special to 'findXXX' and 'selectXXX'
    > methods?


    According to the spec, EJB-QL expressions depend on the abstract
    persistence schemas for your entities, and I don't see any of the
    associated elements in the above DTD excerpt. You should have an
    abstract-schema-name with which to bind your query to the abstract
    "Student" entity, and you should declare the appropriate cmp-field,
    cmr-field, and cmr-relationship elements. (For this simple example,
    however, it looks like you might only need a cmp-field.)


    John Bollinger
    John C. Bollinger, Nov 9, 2003
    #2
    1. Advertising

  3. Hallo John,

    first thanx to your answer. I only posted the statement for the query
    leaving out the rest of the bean including the declaration of the CMR
    fields. The full declaration of the bean within the ejb-jar.xml is
    appended to this article.
    Student extends Person and Person itself is an abstract class. Even if
    Person was a concrete class the expected behaviour: "Table Person has
    columns firstname, lastname, email, phone and Student has
    matriculationNumber, birthday + PersonId_fk" didn't occured.
    I read the feature list of the o/r mapping tool OJB. This enables you
    could to search for a superclass and get also the records from
    extended classes. Polymorphism is suppported as well.
    Even more I found this frustrating but interesting article
    (http://www.mail-archive.com//msg24430.html)
    that states that inheritance "can be done" by establishing an
    association between a user table and a student table.
    Additionally it's very difficult to deal with methods declared within
    the DD, since it doesn't support inheritance.
    Hallo, did I misunderstood something about OO? Is this really
    everything EJB can offer?
    I just want to have all fields and methods of the superclass be
    inherited and accessable as it is common with any other class. Best
    case if the mapping of the fields is efficiently done by the
    AppServer.
    Is there a pattern around howto best implement such stuff? Can you
    point me to a spec describing what's finally possible and what isn't?

    Once again thank you for the response

    Frank


    P.S. if you want to see the complete source code just drop me a line

    =================================================
    <ejb-name>Student</ejb-name>

    <home>org.eka.businesslogic.interfaces.StudentHome</home>
    <remote>org.eka.businesslogic.interfaces.Student</remote>
    <local-home>org.eka.businesslogic.interfaces.StudentLocalHome</local-home>
    <local>org.eka.businesslogic.interfaces.StudentLocal</local>

    <ejb-class>org.eka.businesslogic.entity.StudentCMP</ejb-class>
    <persistence-type>Container</persistence-type>
    <prim-key-class>java.lang.Long</prim-key-class>
    <reentrant>false</reentrant>
    <cmp-version>2.x</cmp-version>
    <abstract-schema-name>Student</abstract-schema-name>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>birthday</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>matriculationNumber</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>firstname</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>lastname</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>email</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>phone</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[This field maintains the
    versionNumber for the last update.]]></description>
    <field-name>versionNumber</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[the primary key for all classes that
    extend this class the id will be populated by a
    sequence]]></description>
    <field-name>id</field-name>
    </cmp-field>
    <primkey-field>id</primkey-field>

    <query>
    <description><![CDATA[get all courses]]></description>
    <query-method>
    <method-name>findAll</method-name>
    <method-params>
    </method-params>
    </query-method>
    <ejb-ql><![CDATA[SELECT DISTINCT OBJECT(s) FROM Student AS
    s]]></ejb-ql>
    </query>
    <query>
    <query-method>
    <method-name>findByMatriculationNumber</method-name>
    <method-params>
    <method-param>int</method-param>
    </method-params>
    </query-method>
    <ejb-ql><![CDATA[SELECT OBJECT(s) FROM Student AS s WHERE
    s.matriculationNumber = ?1]]></ejb-ql>
    </query>
    <query>
    <query-method>
    <method-name>findByLastname</method-name>
    <method-params>
    <method-param>String</method-param>
    </method-params>
    </query-method>
    <ejb-ql><![CDATA[SELECT OBJECT(s) FROM Student AS s WHERE
    s.lastname = ?1]]></ejb-ql>
    </query>
    <!-- Write a file named ejb-finders-StudentEJB.xml if you want to
    define extra finders. -->
    </entity>

    <entity >
    <description><![CDATA[collection of possible status
    values]]></description>

    <ejb-name>StatusValue</ejb-name>

    <home>org.eka.businesslogic.interfaces.StatusValueHome</home>
    <remote>org.eka.businesslogic.interfaces.StatusValue</remote>
    <local-home>org.eka.businesslogic.interfaces.StatusValueLocalHome</local-home>
    <local>org.eka.businesslogic.interfaces.StatusValueLocal</local>

    <ejb-class>org.eka.businesslogic.entity.StatusValueCMP</ejb-class>
    <persistence-type>Container</persistence-type>
    <prim-key-class>java.lang.Long</prim-key-class>
    <reentrant>false</reentrant>
    <cmp-version>2.x</cmp-version>
    <abstract-schema-name>StatusValue</abstract-schema-name>
    <cmp-field >
    <description><![CDATA[]]></description>
    <field-name>value</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[This field maintains the
    versionNumber for the last update.]]></description>
    <field-name>versionNumber</field-name>
    </cmp-field>
    <cmp-field >
    <description><![CDATA[the primary key for all classes that
    extend this class the id will be populated by a
    sequence]]></description>
    <field-name>id</field-name>
    </cmp-field>
    <primkey-field>id</primkey-field>

    <query>
    <description><![CDATA[get all courses]]></description>
    <query-method>
    <method-name>findAll</method-name>
    <method-params>
    </method-params>
    </query-method>
    <ejb-ql><![CDATA[SELECT DISTINCT OBJECT(s) FROM
    StatusValue AS s]]></ejb-ql>
    </query>
    <!-- Write a file named ejb-finders-StatusValueEJB.xml if you want
    to define extra finders. -->
    </entity>
    =================================================
    "John C. Bollinger" <> wrote in message news:<bomcka$op3$>...
    > Frank Ratzlow wrote:
    > > I'm writing a short application and encounter problems with the
    > > declaration of find methods.

    >
    > Have you checked the EJB spec? It's available free from Sun. I'm a bit
    > out of my usual stomping grounds here, having not played much with CMP,
    > but I do have the spec at hand so I'll offer a suggestion or two. (below)
    >
    > > My class looks a bit simplified (leaving all the interface, life
    > > cycle, xdoclet tags bla bla)
    > >
    > > public abstrac class Person {
    > > public abstract String getFirstname();
    > > public abstract void setFirstname(String firstname);
    > >
    > > public abstract String getLastname();
    > > public abstract void setLastname(String lastname);
    > > }
    > >
    > >
    > > public abstrac class Student extends Person {
    > > public abstract long getMatNo();
    > > public abstract void setMatNo(long MatNo);
    > >
    > > public abstract String getLastname();
    > > public abstract void setLastname(String lastname);
    > > }
    > >
    > >
    > > The person class is only created to serve as abstract class to derive
    > > from for specialized classes, so no table for it will be created in
    > > the database.
    > > I wonder why I can only query attributes in Student class that were
    > > directly declared there.

    >
    > I suspect that you are mischaracterizing the problem. This might be,
    > for instance, because your app server is doing more for you than J2EE
    > requires, but less than is necessary to make everything work.
    >
    > > How do I declare a finder method for one of it's inherited fields e.g.
    > > "lastname"?
    > > XDoclet generated for the Student class something like that:
    > >
    > > <query>
    > > <query-method>
    > > <method-name>findByLastname</method-name>
    > > <method-params>
    > > <method-param>String</method-param>
    > > </method-params>
    > > </query-method>
    > > <ejb-ql><![CDATA[SELECT OBJECT(s) FROM Student AS s WHERE s.lastname =
    > > ?1]]></ejb-ql>
    > > </query>
    > >
    > > This looks perfect to me but when deploying I get the following error
    > > message:
    > >
    > > Bean : Student
    > > Method : public abstract Collection findByLastname(String) throws
    > > FinderException, RemoteException
    > > Section: 10.5.6
    > > Warning: Every finder method except findByPrimaryKey(key) must be
    > > associated with a query element in the deployment descriptor.
    > >
    > > I would really appreciate if anyone could give me a hint, what's
    > > wrong. Is there something special to 'findXXX' and 'selectXXX'
    > > methods?

    >
    > According to the spec, EJB-QL expressions depend on the abstract
    > persistence schemas for your entities, and I don't see any of the
    > associated elements in the above DTD excerpt. You should have an
    > abstract-schema-name with which to bind your query to the abstract
    > "Student" entity, and you should declare the appropriate cmp-field,
    > cmr-field, and cmr-relationship elements. (For this simple example,
    > however, it looks like you might only need a cmp-field.)
    >
    >
    > John Bollinger
    >
    Frank Ratzlow, Nov 10, 2003
    #3
  4. Frank,

    I see one or two suspicious things in your abstract schema, but my main
    problem with it is that it doesn't match the implementation classes you
    posted earlier. Evidently you simplified your original example for the
    purpose of raising the question on this forum. I would like to suggest
    that you in fact construct a minimal _complete_ example that exhibits
    your problem, and if that excercise does not in itself help you find the
    problem then post the whole minimal example (implementation class,
    interfaces, complete deployment descriptor). Something based on the
    classes in your original post and exposing only local interfaces should
    be sufficient. It is quite possible that the problem is not where you
    think it is, and it is difficult to analyze a piece at a time,
    especially when the pieces don't match up.


    John Bollinger
    John C. Bollinger, Nov 11, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kgeffen
    Replies:
    1
    Views:
    395
    Sudsy
    Dec 29, 2003
  2. John
    Replies:
    3
    Views:
    308
  3. J. Patterson Waltz III

    Sidestepping inheritance in entity EJBs

    J. Patterson Waltz III, Apr 22, 2004, in forum: Java
    Replies:
    0
    Views:
    356
    J. Patterson Waltz III
    Apr 22, 2004
  4. Andrea Sansottera

    no cmp field defined in cmp ejb

    Andrea Sansottera, Jul 16, 2004, in forum: Java
    Replies:
    0
    Views:
    384
    Andrea Sansottera
    Jul 16, 2004
  5. exquisitus

    Static methods on EJBs ?

    exquisitus, Feb 27, 2005, in forum: Java
    Replies:
    6
    Views:
    865
    Oscar kind
    Mar 1, 2005
Loading...

Share This Page