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)