Entities

With entities we mean what is usually implemented using Entity Beans or EJB3 POJOs (i.e. a persistent entity like a Company or Person for example); in the EJB3 cartridge you will not need to worry about the underlying persistence technology, but you will probably want to know that EJB3 POJOs will be generated for the entities you model. The EJB 3.0 container (i.e. JBoss) adopts a suitable configurable persistence technology. (i.e Hibernate)

In order to successfully generate a single entity it is sufficient to simply model a single class and assign it the <<Entity>> stereotype, this stereotype tells the EJB3 cartridge to treat this class as an entity.

Let's start by modeling a package org.andromda.test and putting a class inside that package, give that class the name Car. Now make sure that entity has the <<Entity>> stereotype, it depends on your UML tool how you need to do that exactly.

You can now try to generate code from your model and take a look at what is generated. If you don't know how to generate code using AndroMDA then head on over to the getting started guide (specifically the section explaining how to setup your first AndroMDA project).

Please note that the EJB3 cartridge is now included in the AndroMDAPP project which means you can generate your project structure using that generator.

If everything went well, all code related to this class will have been generated into the core/target/src project subdirectory, no manual implementation will need to be added at this point.

The EJB3 cartridge changes the conventional entity creation hierarchy. Instead of generating an entity base class with an entity implementation class, there are 2 ways the EJB3 cartridge can generate your entity POJOs.

  • In most cases, your entities will only model classifier scoped finder methods. If there are no classifier scoped operations, then the cartridge auto generates (and will regenerate) your entity components for you. The entity components include the entity POJO and the DAO components associated with the entity.
  • The alternative is to have an embeddable/mapped superclass with an entity class that inherits from this mapped superclass. This is the case where the entity models instance scoped operations and are involved in non-inheriting hierarchies. However once you introduce inheritance, this changes. To find out more about inheritance, go to the inheritance section.
  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

The class we have modeled does not have any properties, however, by default, AndroMDA creates the id attribute of type datatype:Long if no identifier (primary key) attribute has been modeled by the user. It is possible to override these settings in the namespace properties for Maven or the namespace properties for Ant. Click here if you want to know more about the default namespace properties you can set.

Entity Operations

You may also model operations on an entity, this will generate them as methods in the resulting components. Operations can be classifier scoped (static in Java) where they will be underlined in UML diagrams as shown below. You may also define instance scoped operations if you require.

In general, operations will not be defined in the mapped superclass. They will be defined in the inheriting subclass. This has consequences when dealing with a multi-tier inheritance hierarchy. Refer to the inheritance howto for further information. This also implies that operations are only added to the implementation class on the first run of AndroMDA. Operations defined in the UML model must be manually added to the implementation class afterwards. This shouldn't cause any issues as the developer would have to define the operation implementation anyway to correspond to the abstract definition in the mapped superclass. The primary purpose for this strategy is to avoid having to annotate the entity operation with @javax.persistence.Transient annotation in both the mapped superclass and the inheriting implementation class.

Classifier scoped operations marked as query operations, known as finder methods, modeled on entity are not rendered in the entity components, but instead added to the DAO components.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • CarEmbeddable.java
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

Entity operations modeled as Query operations are discussed further in the Query Howto. In general entities should NOT contain any business logic. The EJB3 cartridge, like other persistence modeling cartridges, uses the session facade pattern to contain business logic in session bean operations while typical CRUD persistence operations are provided through the DAO layer.

The above example entity models allCarsAreRented() as classifier scoped and isRented() as instance scoped. Both will be added to the entity implementation subclass Car. The bulk of the entity detail, including much of the metadata exists within the CarEmbeddable class. In such cases where non-query operations exists for an entity, the implementation class is generated once only and will not be overridden.

Entity Relation Table

Your relational table's name which persists an entity is determined by default from the actual entity name. To change the table name assignment in the @javax.persistence.Table annotation, set the andromda_persistence_table tag on the entity. The same tag can be modeled on a Many-To-Many association relationship.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

Primary Key - Identifier

To assign an entity's attribute as a primary key, you must assign the <<Identifier>> stereotype to it. If this identifier is not part of a composite primary key, then @javax.persistence.Id annotation is added to the attribute getter method.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

An entity identifier attribute's table generator can be modeled via the andromda_persistence_generator_type tag on the identifier attribute ONLY. This is used to model the primary key generation strategy associated with the @javax.persistence.Id annotation for an entity attribute. Currently, the EJB3 cartridge supports:

  • The default type is AUTO
  • TABLE
  • SEQUENCE
  • NONE

The table generator name can be set using the andromda_persistence_generator_name tag. This must be a unique name which is referenced by one or more classes to be the generator for an entity bean. By setting the andromda_persistence_generator_source_name tag, you can specify either the table name that stores the generated ids or the sequence name which is the name of the database sequence object used to get the ids. For table generator types, you must specify the andromda_persistence_generator_pkcolumn_value tag which defines the primary key value in the generator table to identify the specified generated value from other values. For sequence generator types, you can specify the initial value of the sequence using andromda_persistence_generator_initial_value tag and the allocation size by andromda_persistence_generator_allocation_size tag. The allocation size sets the amount to increment by when allocating id numbers from the sequence generator.

Unique Attributes

In case you want an entity's attribute to be unique for all instances of that entity's type you should assign the <<Unique>> stereotype to it. This will define the corresponding unique element in the @javax.persistence.Column annotation.

Attribute Fetch Type

By default, the EJB3 cartridge and EJB 3.0 spec defines an attribute fetch type as eagerly fetched. To specify an attribute as lazy fetched, we hint to the persistence container by modeling the andromda_persistence_fetch_type tag on the attribute. Under normal circumstances, you do not need to specify this tag.

Transient Attribute

To indicate an attribute as transient (not persisted by the persistence container), you model the <<Transient>> stereotype on the attribute. This adds the @javax.persistence.Transient annotation to the attribute.

Insertable Attribute

To include the mapped column in the SQL insert statement, you set the insertable property on the @javax.persistence.Column annotation which is done by modeling the andromda_persistence_column_insert on the attribute. By default, this is set to true, so it only needs to be specified if you want the column to be initialized using the database default value.

Updatable Attribute

To include the mapped column in the SQL update statement, you set the updatable property on the @javax.persistence.Column annotation which is done by modeling the andromda_persistence_column_update on the attribute. By default, this is set to true, so it only needs to be specified if you want the column to be updated using by the database automatically.

Version Attribute

To specify an attribute as a version attribute, where it becomes the optimistic lock value for an entity, you model the <<Version>> stereotype on this attribute. This can only apply to ONE attribute per class. Attributes with this stereotype will not be updated by the persistent container. The attribute can only of the following types:

  • int
  • short
  • long
  • Integer
  • Short
  • Long
  • Timestamp

Attribute Multiplicity

It's possible to configure the multiplicity of an entity's attribute, by setting it to [0..1] an attribute is not required and is allowed to be set to null; setting the multiplicity to a value greater than 0 means the attribute is required. In the former case the nullable element will be set to true for the @javax.persistence.Column annotation on the attribute. The following class assigns a multiplicity of [0..1] to the name attribute which means name can be null.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

Please note that some UML tools have a default multiplicity value for attributes when not specified by the user, these default values may differ from tool to tool.

Constant Attributes

To define static constants within an entity POJO (constants that are not resource injections), model a classifier scoped attribute (static in Java). These attributes are defined as static with public visibility. Constants must define a default value in the model. The following entity defines 3 constants for type.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

Nullable Parameters

If you want an operation to have a parameter which is allowed to be null then simply assign the <<Nullable>> stereotype to that parameter. By default service operations throw an exception when a null argument has been passed.

It is possible to globally disable checking for null arguments, so you will never need to specify the <<Nullable>> stereotype; to do so just specify the parameterRequiredCheck namespace property to have the false value.

LOB BLOB/CLOB Attributes

An attribute can be specified as either a BLOB or CLOB field. This is modeled by setting the attribute type to datatype::Blob or datatype::Clob. This will add the @javax.persistence.Lob annotation to the entity attribute. The EJB3 cartridge will assign a default Java type based on the Java mappings specified in AndroMDA. For a Blob, the default is byte[]. For a Clob, the default is String. To override the default types, you can model the andromda_persistence_lob_type tagged value to the fully qualified name of the required type.

For BLOB fields, the attribute type must be modeled as one of:

  • Byte[]
  • Serializable type
  • java.sql.Blob

For CLOB fields, the attribute type must be modeled as one of:

  • char[]
  • Character[]
  • String
  • java.sql.Clob

The default fetch type for a LOB typed attribute is lazy. To assign a LOB attribute to be eagerly fetched, model the andromda_persistence_fetch_type tag on the attribute.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

This example models the attribute named type as a CLOB where the corresponding column in the table will be of type String and the cartridge will set the fetch type for the attribute to eagerly fetch. The attribute information is defined as a LOB, but it's of type char[].

Column Specifics

Here is an example of some of the tagged values available to model on entity attributes.

  • Auto-generated source that does not need manual editing
  • Auto-generated source that should be edited manually
  • File that is affected by the modifications applied in this section
  • Car.java
  • CarDao.java
  • CarDaoBase.java
  • CarDaoImpl.java
  • CarDaoException.java

To change the default naming schema for the relational table column, model the andromda_persistence_column tag on the attribute.

You can set the column length for the relational database table for string based columns by modeling the andromda_persistence_column_length tag on the attribute.

If the column is defined as a decimal column (i.e. float or double), you can model the precision and scale of the column by setting andromda_persistence_column_precision tag to set the precision of the decimal column and/or andromda_persistence_column_scale tag to set the scale for a decimal column, on the attribute.

In order to change the creation DDL for the column in the relational table, you can model andromda_persistence_column_definition tag on the attribute.

Listener Callback

In some cases, setting up lifecycle event callbacks for the entity beans can be quite useful. The EJB3 cartridge provides the facility to define these callback methods in the listener class. This class is NOT generated by default. To find out more information, click on Listener Callback.

Next

Next we will learn about the DAO components generated for the entities, click here to continue.