Right about the time this module matured, Enterprise Java Beans (EJBs) fell out of vague. Nevertheless, EJBs still have their place in enterprise software and JavaGen makes them as easy to create as POJOs (in fact you model them as POJOs). The JavaGen EJB module is feature rich and vendor neutral.
JavaGen generates Java source code decorated with XDoclet tags. For example this diagram

produces the following CMP EJB code
/**
* @ejb.bean
* name="Account"
* type="CMP"
* cmp-version="2.x"
* jndi-name="ejb/Account"
* local-jndi-name="ejb/AccountLocal"
* use-soft-locking="false"
* view-type="local"
* primkey-field="userId"
* @ejb.persistence
* table-name="account"
* @ejb.transaction
* type="Required"
...
*/
abstract public class AccountEJB implements EntityBean
{
/**
* CMP primary key accessor.
* @ejb.pk-field
* @ejb.interface-method
* view-type="local"
* @ejb.persistent-field
* @ejb.persistent
* column-name="userid"
* @jboss.column-name
* name="userid"
*/
abstract public java.lang.String getUserId();
/** CMP primary key mutator. */
abstract public void setUserId(java.lang.String userId);
...XDoclet is also a primary means of customizing the generated code.
You can modify the generated code and mappings by attaching @ejb
tags in the UML at the class, attribute or association levels. JavaGen passes through
whatever is present in the UML (including source code in method bodies) only generating
what is necessary to produce a working EJB mapping
(see Customization).
When JavaGen encounters a class with the <<cmp>> stereotype it generates a Container Managed Persistence (CMP) EJB attaching XDoclet metadata for database mapping. XDoclet is then applied to generate the EJB support classes and deployment descriptors. If you use JAM for the build process, all the assembly, packaging, deployment and testing is ready to use out-of-the-box.
CMPs are modeled as POJOs (Plain Old Java Objects) in UML, making a complex technology simple
to implement. For example, from the Account class above, JavaGen can generate:
Additional support classes (discussed below) that can also be generated are:
CMP EJBs require one or more primary keys. By default, if you do not provide one, JavaGen will create one for you. This behavior can be disabled with the following property setting:
<property name="javagen.cmp.generate.keys" value="none"/>
Primary keys come in two flavors based on the stereotype you use:
| Stereotype | Description |
|---|---|
| <<synthetic-key>> | Synthetic keys are generated automatically by the application when a new CMP is created. |
| <<primary-key>> | This primary key type is often called a natural key (think email address) and must be supplied by the user or application. |
If you specify more than one primary key, JavaGen will generate a compound primary key class and the required support code.
Null primary key values are used to determine if an object is new when making sql
insert or update decisions. Therefore, primary keys must be a java.lang.String
or one of the integer wrapper types: (java.lang.Integer
or java.lang.Long).
For synthetic keys, JavaGen supplies a portable EJB implementation, AutoPk. If not already in your local repository, AutoPk can be downloaded here. It must be in your classpath and be packaged into your deployment EAR file.
JAM users should create a dependency in the project.xml file as follows (substituting the proper version):
<dependency> <id>javagen+autopk-ejb</id> <version>1.0.2</version> <type>ejb</type> <properties> <ear.bundle>true</ear.bundle> </properties> </dependency>
JavaGen treats any non-static, not-transient attribute as a persistent property. You can suppress this behavior by attaching the <<field>> stereotype to an attribute.
In the EJB context, UML associations are always drawn between two <<cmp>>
classes. Associations can be one-to-one, one-to-many, many-to-one or many-to-many.
In most cases JavaGen will generate an appropriate mapping,
but you can customize the results by attaching XDoclet tags on the association ends
as UML Tagged Value pairs (see Customization).
It is good practice to name your association ends, as this results in higher quality generated code with more meaningful property, method, column and table names. If no name is found on an association end JavaGen uses the class name - which works most of the time. However, in situations were you have multiple relations between the same two entities or relations to a single entity (i.e. self referential relations) you will encounter naming conflicts if you do not assign unique names to the association ends.
Optionally, you can use singular or plural names to reflect the cardinality (one or many) of the relation end.
JavaGen does not support association classes. It is easy to work around this limitation by making the association class an entity and using two one-to-many associations for either side. Because JavaGen achieves its EJB mapping using XDoclet tags, any limitations in XDoclet limit JavaGen's capabilities.
When working with one-to-one or one-to-many relations there are two ways to form associations:
| Key | Description |
|---|---|
| Foreign Key | Formed between a foreign key in one table and a primary key in another, this is the default and recommended mapping type. JavaGen picks the foreign key end based on cardinality, visibility and efficiency constraints. |
| Primary Key |
Formed between the primary keys of two tables, this type of relationship must be explicitly specified using Tagged Values on the association ends. For example
designates the primary key of the target class to be used instead of a foreign key. TODO: this needs to be replaced with an XDoclet tag |
Associations are generated true to their UML representation:
composition will generate parent/child relation with cascading delete behavior.Unidirectional and bidirectional relations are set with the
navigable setting.* cardinality generate NULLABLE foreign key mappings whereas
1..* ends generate NOT-NULL foreign key mappings.Many-to-many associations result in a third association table
being generated,
otherwise they are similar to one-to-many associations. If you need more control over
the mapping details, many-to-many associations can be modeled as two one-to-many associations
with a common association
class in the middle.
Unlike Hibernate, with EJBs you can have any collection type you like, as long as it's a
java.util.Collection.
Although JavaGen generates server independent Java code, to deploy correctly most servers require
server-specific deployment descriptors such as jboss.xml and
weblogic-ejb-jar.xml.
JavaGen supports this by generating server-specific XDoclet tags.
JavaGen can generate tags for more than one application server using the following comma-delineated property:
<property name="javagen.servers" value="jboss3,resin2,weblogic8"/>
The currently supported servers are:
It is relatively easy for us to add new servers as long as they are supported by XDoclet and the client (that's you) is willing to help out with testing.
Data Definition Language or DDL SQL scripts are simply SQL commands to create and drop database tables. JavaGen will generate a database-specific DDL if you set the following property:
<property name="javagen.sql.flag" value="true"/>
The database vendor can be set using:
<property name="javagen.database" value="mysql"/>
The following are valid database values:
Session EJBs come in two flavors: Statefull and Stateless.
Statefull session beans are widely regarded as too heavyweight and most applications employ other means to maintain client state.
Although JavaGen can generate both types of session beans, we restrict our discussion to the more successful of the two.
Transparent multi-threading and high scalability qualities make stateless session beans an ideal technology for providing services in distributed environments.
To generate a Stateless Session EJB use the <<stateless>> stereotype:

Things get more interesting when you combine CMPs with a session beans. For example, this diagram

will generate import statements for the
local interface, local home and util classes, as well as generating a getAccountLocalHome()
method.
JavaGen also takes care of other subtle details. Remember you're designing with POJO representations
of EJB implementations, the actual implementations have different names and locations. For
example the return type of the create() method above must be converted from
Account to AccountLocal.
You can associate a CMP with a Data Access Object or DTO. Besides providing an efficient mechanism for passing data between client and server, JavaGen generated DTOs can be converted to XML and back, forming the basis for web services and database import/export. See the next diagram and the DTO Module for details.
Rather than expose CMPs to clients, standard practice is to go through an intermediary object called a session facade. A session facade is nothing more than a stateless session EJB that manages access to the CMP while providing additional services such as transaction handling and security.
CMPs combined with session facades, DTOs and XML data-binding services provide a solid foundation to build your distributed application on.
JavaGen will generate a working session facade just by adding the <<gen-crud>> stereotype to the CMP dependency as shown here:

The resulting session bean provides Create, Read, Update and Delete (CRUD) functionality from
the generated getAccountData(), setAccountData() and
deleteAccount() methods. The DTO is used to pass data to and from the CMP.
JavaGen primarily supports Container Managed Persistence (CMP) and Stateless Session EJBs for both versions 2.0 and 2.1. There are no plans to support Bean Managed Persistence (BMP) or Statefull Session EJBs because these specifications are widely regarded as bad ideas. However, we are interested in developing Message Driven Beans (MDBs) and upgrading to EJB 3.0. which will likely happen when a loyal user makes a persuasive request ;-)
The primary development application server has been JBoss 3.x and 4.x. Weblogic, Websphere and Resin are also supported but may not be as up to date. Again, code usually gets updated when clients are willing to work with us and help out with testing.
Because JavaGen utilizes XDoclet for generating the support classes and deployment descriptors, XDoclet shortcomings also create limitations for JavaGen. We have developed effective work-around's for most these of issues, in particular the use of XSLT Descriptor Processing.
To allow for using EJBs with Hibernate, the <<cmp>> was used instead of <<entity>> for CMPs. I you're not mixing the two technologies, you can use whatever stereotypes you like, see Renaming Stereotypes.
| Stereotype | UML Element | Description |
|---|---|---|
| <<cmp>> |
Class
| Generates a CMP entity bean mapping. See CMP EJBs |
| <<stateless>> |
Class
| Generates a Stateless session bean mapping. See Stateless EJBs |
| <<statefull>> |
Class
| Generates a Statefull session bean mapping. See Statefull EJBs |
| <<primary-key>> |
Attribute
| Generates a primary key mapping. See Primary Keys |
| <<synthetic-key>> |
Attribute
| Generates a auto increment (synthetic) primary key mapping. See Primary Keys |
| <<field>> |
Attribute
| Treats attribute as non-persistent. See Persistent Properties |
| <<gen-crud>> |
Dependency
| Generates Create, Read, Update and Delete methods. See Session Facade |
Set these properties in your build.xml or props-javagen.xml file:
| Property | Default | Description |
|---|---|---|
| javagen.ejb.flag |
false
| Switch that turns on EJB module, set to true to activate. |
| javagen.sql.flag |
false
| Generates DDL SQL scripts to create and drop tables. |
| javagen.database |
hypersonic-sql
| Database vender used in generating DDL. See the list of valid values here. |
| javagen.servers |
jboss3
| Comma-delineated list of application servers to generate XDoclet tags for. See Servers |
| javagen.dto.castor.xml.flag |
false
| Generates Castor XML databinding to DTO objects. |
| javagen.cmp.generate.keys |
cmpClasses
| Adds primary keys to CMPs when missing. Valid values: cmpClasses, cmpWithAssociations, none |
| javagen.cmp.view |
local
| Default EJB CMP view type. Valid values are: local, remote and both. Override using view-type attribute on @ejb.bean and @ejb.method XDoclet tags. |
| javagen.session.view |
both
| Default EJB session view type. Valid values are: local, remote and both. Override using view-type attribute on @ejb.bean and @ejb.method XDoclet tags. |