Fun with XDoclet.
I tried to get a simple CMP bean to work with the new XDoclet
features. I used the new @ejb.persistence. I did not get any error messages, but
the CMP field mapings did not get generated in the resin.ejb file.
Then Ara of XDoclet fame told me: "That's because the resin module doesn't support ejb.persistence tags
yet."
So I set out to learn a few things about XDoclet with some help from Erik Hatcher...
I modified the resin CMP mapping template. It was really easy to change.
I had to modify the file resin_ejb.xdt file. I tested it and it works for simple CMPs.
Then Erik told me to make it backwards compatible with the old way, and I did.
Then I started to wonder about relationship mappings.....
I checked and I could not find any standard xdoclet cmr mappings either
documented or in the examples that ship with XDoclet.
This seems a little harder than just changing the template like Resin CMP
support. Any direction on how to attack this would be great! I am going to
pick Erik's brain this weekend, and read the XDoclet chapters in his Ant
book for prep.
My idea on how to manifest cmr support in the tags.....
Add an extra parameter to @ejb.relation called relation-column-name and target-relation-column-name (for unidirectional support).
This idea got shot down by Aslak Hellesøy [aslak.hellesoy@netcom.no]. He stated the following:
"""
I would study the existing proprietary @tags and try to come up with a
common denominator. Don't forget that a foreign key is _not_ the same as a
foreign key _column_. Some foreign keys consist of multiple foreign key
columns, and the tags would have to account for that. This means that it's
*no* good to add key/foreign key attributes to the @ejb.relation tag (which
might seem intuitive at first). We need a separate tag for foreign keys, so
that it can be repeated once for each foreign key column in the foreign key
that corresponds to the relation. Picture:
+---+ +---+
| X | | Y |
+---+ +---+
|*a |\__/| m |
|*b |/ \| n |
+---+ +---+
This is one relation between table/EJB X and Y. It has one foreign key that
consists of 2 foreign key columns. -So we need 2 tags to describe the
relation.
Have a look at
http://boss.bekk.no/boss/middlegen/samples/airline/ejb/ReservationBean.java.
html, more specifically the getPerson() method to see an example. You'll see
single-column foreign keys (which is the most common scenario). -But we
should support the less common scenario as described above.
Also look at a "picture" of the database:
http://boss.bekk.no/boss/middlegen/ (click the screenshot).
As you see, both JBoss and WebLogic identify the foreign key columns by
declaring the column name. -But! JBoss uses the java bean property - in this
case "flightId" which corresponds to the getFlightId() method - to identify
the primary key column. A primary key column will _always_ have a
corresponding getter/java property in an EJB, so this is a safe assumption.
However, you might have a foreign key column for which there is no
corresponding getter/java property, so in order to identify the foreign key
column, you have to declare the database column name. WebLogic uses a
different approach, which is also safe: Use the rdbms column name for both
pk and fk.
Going for the JBoss "way", using java for pk columns and sql for fk columns
is the way to go IMO. It's possible to deduce the corresponding rdbms pk
column for an EJB pk field by looking at the @ejb.persistence tag, so the
WebLogic descriptors can still be generated correctly. Therefore my approach
is:
@rdbms.relation
foreign-key-column="some_database_column"
primary-key-field="someJavaPropertyWhoseMethodHasAnEjbPersistenceTagThatMaps
ToTheRdbmsColumn"
Now a little challenge: How would you represent the non-common info? JBoss
has a fk-constraint="true|false" proprietary attribute on the current
@jboss.relation tag. Where do you specify that now? It would be best to
specify it on the same @rdbms.relation tag. It bloats the tag a little bit
with "proprietaryness" but it's better than adding a third tag. -And in the
case where you have a foreign key that consists of 2+ columns you'd have to
invent an additional name attribute so you could link the jboss info to the
correct @rdbms.relation tag. Therefore:
@rdbms.relation
foreign-key-column="some_database_column"
primary-key-field="someJavaPropertyWhoseMethodHasAnEjbPersistenceTagThatMaps
ToTheRdbmsColumn"
jboss-fk-konstraint="true"
I.e. any non standard attributes are still on the same tag, but with a
prefix indicating that it's not standard. (By the way this is the same
approach we're probably going to use for proprietary EJB-QL extensions on
the @ejb.finder tag. There will be weblogic-ql and jboss-ql attributes.)
I also suggest you read my "Synergy" post on my (old) blog (in case you
aren't confused enough by now ;-)
http://www.freeroller.net/page/rinkrank
"""
Then I asked....
> Is anyone working on this? I think this should be added to this release in
> beta.
>
and he replied:
"""
Nobody is working on this, and it would be great if you wanted to look at
it. It shouldn't be any more comlicated than what you already did for
@ejb.relation in Resin. -The hard part is coming up with the "right" tags,
and I have a good tummy-feeling that my proposal a few lines up is the way
to go.
"""
BTW I just got permission to include the XDoclet stuff I wrote
for Mastering
Tomcat for the Xdoclet documentation. This is a tutorial on XDoclet mainly
geared toward Servlets, Custom Tags and Struts. Ara A. said he was
interested in including this as part of the docs. or at least link to it
from the docs. I need to change the examples to use dots instead of colons
and test it with the version of Xdoclet in beta, other than that....