An abstract example
As said before, using Xdoclet, we merely have to focus on the implementation of our beans, and let Xdoclet generate all the necessary interface classes and deployment descriptors for us.
Consequently, the files involved in a (unidirectional) one-to-one CMR are Table1Bean.java
andTable2Bean.java
. In the concrete example section, we will also take a closer look at the generated jboss.xml
, ejb-jar.xml
, jbosscmp-jdbc.xml
though.
(The ejb-jar.xml
file contains elements that describe relationships and navigability. The jbosscmp-jdbc.xml
contains the details of mapping to a database, hence are application server (container) specific.)
I’ll omit discussing the build.xml
which is supposed to deploy your beans and the xdoclet.xml
, which invokes Xdoclet to generate the necessary sources from the source+Xdoclet tags. (also known as ejb-generate.xml
, see this post). In my case these are taken care of by Eclipse, but you’re supposed to be acquainted enough with these files for your own favourite IDE or command line interface, otherwise this long post would be even longer.
Let’s get down to business. Suppose Table1Bean
wants to (unidirectionally one-to-one) refer to Table2Bean
.
To make this possible
Table1Bean
must have at least a primary key fieldtable1ID
with associated database columntable1_id VARCHAR
(of course, any simple (not compound in CMR fields!!) type primary key definition will do), andTable2Bean
must at least have a foreign key fieldtable1IDfk
with associated database columntable1_id_fk VARCHAR
.
I’ll assume you can set-up the entity beans without relations (if not, I’ll recommed this tutorial once more).
Now you have to add Xdoclet tags for establishing the (unidirectional one-to-one) relation for
- the bean deployment descriptor,
ejb-jar.xml
, using the@ejb.relation
tag and - the (JBoss) application server, using the and
@jboss.target-relation
tag
You have to add these tags to the comment section of the definition of the getter of your CMR field, so in Table1Bean.java
/** * ...omitted normal method comments with @return stuff etc... * * @ejb.interface-method * * @ejb.relation * name="table1-refers-to-table2" * role-name="Table1ToTable2" * cascade-delete="yes" * target-cascade-delete="yes" * target-role-name="Table2ToTable1" * target-ejb="Table2" * * @jboss.target-relation * related-pk-field="table1ID" * fk-column="table1_id_fk" */ public abstract ArticleLocal getArticle();
It is not necessary to use the @ejb.ejb-ref
class scope tags, you use these in e.g. your facade stateless session beans.
Now look very good what’s happening here. It took me a lot of time to figure out! Since we have unidirectionality here (the “blind side” in the EJB Xdoclet tag documentation is the side that is referred to in the unidirectional case), we have to specify the target side with the target-rolename
field. Not complying with this rule will result in deployment errors. The target-ejb
is compulsory (of course).
The @jboss.target-relation
has a field designating the primary key field of the originating bean (related-pk-field
) and a field designating the foreign-key database column of the referred to bean, Table2Bean
(fk-column
). Finally the cascade-delete
means that the associated bean is deleted, once the main bean is. This ensures referential integrity.
In our concrete example we’ll look at the resulting ejb-jar.xml
, jboss.xml
and jbosscmp-jdbc.xml
.
Now upon creation of a Table1Bean
item (consisting of fields in Table1bean
and Table2Bean
), we must
- Create an instance of
Table1Bean
- Create an instance of
Table2Bean
- Make a link/reference from
Table1Bean
toTable2Bean
using the CMR field.
According to the EJB 2.x spec, the CMR field can only be set in the ejbPostCreate()
method! This method must have the same signature as the ejbCreate()
method, of course.
Using the CMR field associated get-method, you are able to retrieve a reference to Table2Bean
. Looking ahead to one-to-many relation ships, we can already see that this get-method will return a Collection, instead of a reference to a single bean.
With these ingredients, you should be able to finish your application.
Finally, I want to stress once more that besides the JBoss tags in Xdoclet, there are corresponding tags for all kinds of application servers, such as JOnAS, Bea’s Weblogic and many more.
Did it and worked. In fact the CMR element -Container Managed Relations- is an obvious missing point. Do you know where I can get some good sources for CMR?
Thanks!
Hi everyone:
I would like to know if there’s possible to generate querys in the .java’s bean with xdoclect, something like Jboss IDE or hibernate. I must define relationships and create new querys and can’t do enything of that with my Lomboz Eclipse plugin and Jboss server.
I would be greateful at any kind of help
Regarding Comment 4, that’s because it’s after the “@jboss.target-relation” tag, which refers to the blind side of the relation. In the case which you mentioned, one would use the “@jboss.relation” tag, which makes it work from the other side.
It took me very long to figure this out…somehow most tutorials on the net use that kind of example with the CMR Relation on the blind side, which i personally find not very intuitive for a first example. When trying it with the tags on the side with the foreign key column this produces “unknown column in where query” exceptions.
I did it and it works correctly (after some hacks :o)).
Now i want to make tests around it. need i use cactus? is there another solution?
I dont want to kludge without another ejb. 🙁
Thank you
Breno Leitão.
http://lcr.icmc.usp.br
For anyone who searches for good example code:
Maybe you like to look at
http://xpetstore.sourceforge.net/
It is quite simple but has no bedirection m:n relationship.
I got it!!!!
“ss� and me have the following problem:
XDoclet generates an empty {field-name} and {column -name}.
Here is the reason for that behaviour:
We got the source via copy and paste from this website. This leads us to the following line:
The closing quotation mark is non ASCII! This confuses XDoclet. Just replace it with the correct one (“) and everything works properly.
Yours
Arne
This example is part of quite a large project in Eclipse, hence it is not possible to compose such a JAR instantly. However, I think it is a very good idea. Moreover, the statistics show that many people are struggling with these issues and are consulting my post.
Although I cannot promise to deliver the JAR file tomorrow, I’ll do my best to make it available soon. If so, I’ll make a new post, instead of changing this one. Of course, I’ll leave a comment referring to the new post.
If anyone else already has such a JAR file (preferrably based on my example) and is willing to share his/her efforts with the rest of the world, please let me know.
Regards,
It would be *very* nice if you can zip a complete working example (inclusive build.xml) and give it for download. Please.
Yours
Arne
Btw.: Your examplanations are very understandable.
I got the same problems as “ss” has.
It would be *very* nice if you can zip a complete working example (inclusive build.xml) and give it for download. >> Please < <
Yours
Arne
Btw.: Your examplanations are very understandable.
From your comment I cannot see what you find confusing. I did not post the database schema, since the intention was to let the container create the schema for me. But now that the schema has been created, I can post it, of course!
An article is created in the Hypersonic database with this SQL statement:
The PUBLICATION_ID_FK is primary key and foreign key at the same time for the article table. This is sound, since we are dealing with a one-to-one relationship here.
A bibliography is created with:
I hope this helped!
Looks like you may have things the wrong way around? Isn’t Table 2 actually referring to Table 1? Rather confusing. Also I find the Concrete example even more confusing! It would be better accompanied by a database schema to refer to.
Thanks a lot for the tutorial. however,
i used the following in my ant build script, but i had problems generating the <key -fields/> in jbosscmp-jdbc.xml.
And hence i had problems deploying my bean. It threw the following exception.
org.jboss.deployment.DeploymentException: Atleast one role of a foreign-key mapped relationship must have key fields (or <primkey -field> is missing from ejb-jar.xml): ejb-relation-name=FolderMayContainDevices
Can you please help.
the build.xml was as follows:
It was the first tutorial I found, which really helped me, to understand, how to make cmr with Xdoclet.
Thanks for it.
Janos
The promised follow-up is available here.