- Entity Bean
- Session Bean
- Message Bean
- Relationships
- Going Forward
Relationships
Although using XDoclet to construct relationships between entity beans is much easier than creating the deployment descriptors by hand, it is still fairly difficult. First, I create a second entity bean that I will then connect to the first one:
package com.dzrealms.example.entity; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.RemoveException; import javax.ejb.CreateException; /** * @ejb.bean name="ExampleChildBean" * jndi-name="example/remote/ExampleChildBean" * local-jndi-name="example/local/ExampleChildBean" * cmp-version="2.x" * primkey-field="ID" * schema="ExampleChild" * * @ejb.persistence table-name="exampleChild" * * @ejb.interface remote-class="com.dzrealms.example.entity.ExampleChildRemote" * local-class="com.dzrealms.example.entity.ExampleChildLocal" * * @ejb.home remote-class="com.dzrealms.example.entity.ExampleChildHomeRemote" * local-class="com.dzrealms.example.entity.ExampleChildHomeLocal" * * @jboss.entity-command name="mysql-get-generated-keys" * * @jboss.unknown-pk class="java.lang.Integer" * auto-increment="true" */ public abstract class ExampleChildBean implements EntityBean { /** * @ejb.create-method * @return Primary Key * @throws javax.ejb.CreateException */ public Integer ejbCreate() throws CreateException { return null; } public void ejbPostCreate() { } /** * @ejb.interface-method * @ejb.persistence * @return Primary Key */ public abstract Integer getID(); /** * @param i Set the primary key */ public abstract void setID(Integer i); /** * @ejb.interface-method * @ejb.persistence * @return the test variable */ public abstract String getTestVariable(); /** * @ejb.interface-method * @param s sets the test variable */ public abstract void setTestVariable(String s); public void setEntityContext(EntityContext context) { } public void unsetEntityContext() { } public void ejbRemove() throws RemoveException { } public void ejbActivate() { } public void ejbPassivate() { } public void ejbLoad() { } public void ejbStore() { } }
With the child bean now defined, I will create a relationship between the example bean and the child bean. The example bean will have a reference to a collection of child beans, whereas the child bean will have a reference to its single parent bean. This represents a one-to-many relationship. To start, I add the following two methods to the ExampleBean (parent) so that it can get and set a collection of child beans:
/** * @ejb.interface-method * * @ejb.relation name="Parent-to-Children" * role-name="Parent-has-many-Children" * target-ejb="ExampleChildBean" * target-role-name="Child-has-one-parent" * * @jboss.relation fk-column="parentID" * related-pk-field="ID" * * @return */ public abstract Collection getChildren(); /** * @ejb.interface-method */ public abstract void setChildren(Collection c);
The tags break down as follows:
ejb.interface-method |
This tag tells XDoclet to include this method in the local and remote interfaces |
ejb.relation name |
This tag is the name of this relationship. This name must match on both sides if this is a bidirectional relationship. |
ejb.relation role-name |
This tag is the name of the role of this object in relation to the relationship. This name is used to link the relationship between the ejb-jar.xml and the server-specific deployment descriptor. |
ejb.relation target-ejb |
This tag tells XDoclet where to look for the other side of the relationship and tells it what object this relationship links to. |
ejb.relation target-role-name |
This tag tells XDoclet what the name of the other side of the relationship is. |
jboss.relation fk-column |
This is a JBoss-specific tag that tells JBoss what the column name is for the foreign key in this relationship. |
jboss.relation related-pk-field |
This is a JBoss-specific tag that tells JBoss what the primary key field is that the foreign key column links to. |
The end result of this block of tags is a method that will retrieve all the child entity objects in a collection that are related to this parent instance. If you notice, the child entity object does not have a getter and setter for the foreign key, it is unnecessary and considered redundant because the container handles the relationship for us. To add an item to the list of children, it merely needs to be added to the collection, and the container will handle all the keys for us.
The child side of this relationship looks very similar:
/** * @ejb.interface-method * * @ejb.relation name="Parent-to-Children" * role-name="Child-has-one-parent" * target-ejb="ExampleBean" * target-role-name="Parent-has-many-Children" * target-multiple="true" * * @jboss.relation fk-column="parentID" * related-pk-field="ID" * * @return */ public abstract ExampleLocal getParent(); /** * @ejb.interface-method */ public abstract void setParent(ExampleLocal el);
The one major difference is the additional tag: @ejb.relation target-multiple="true". This tells XDoclet to configure this side of the relationship as a "many." Otherwise, XDoclet (and, by extension, the container) will assume a one-to-one relationship. The rest of the tags are simply the reverse of the parent listed above.