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

F

Frank Ratzlow

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
(e-mail address removed)

JBoss 3.2, XDoclet 1.2b3, sdk 1.4.2 OS: Windows XP
 
J

John C. Bollinger

Frank said:
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
(e-mail address removed)
 
F

Frank Ratzlow

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/[email protected]/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
(e-mail address removed)

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 said:
Frank said:
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
(e-mail address removed)
 
J

John C. Bollinger

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
(e-mail address removed)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top