CMP Fields


CMP fields are declared on the bean class as abstract getter and setter methods that follow the JavaBean property accessor conventions. The gangster bean, for example, has a getName() method and a setName() method for accessing the name CMP field. The following sections look at how to configure these declared CMP fields and control the persistence and behavior.

CMP Field Declaration

The declaration of a CMP field starts in the ejb-jar.xml file. On the gangster bean, for example, the gangsterId, name, nickName, and badness are declared in the ejb-jar.xml file as follows:

 <ejb-jar>   <enterprise-beans>     <entity>         <ejb-name>GangsterEJB</ejb-name>         <cmp-field><field-name>gangsterId</field-name></cmp-field>         <cmp-field><field-name>name</field-name></cmp-field>         <cmp-field><field-name>nickName</field-name></cmp-field>         <cmp-field><field-name>badness</field-name></cmp-field>     </entity>   </enterprise-beans> </ejb-jar> 

Note that the J2EE deployment descriptor doesn't declare any object-relational mapping details or other configuration. It is nothing more than a simple declaration of the CMP fields.

CMP Field Column Mapping

You do the relational mapping configuration of a CMP field in the jbosscmp-jdbc.xml file. The structure is similar to that of the ejb-jar.xml file, with an entity element that has cmp-field elements under it, with the additional configuration details.

The following shows the basic column name and data type mappings for the gangster bean:

 <jbosscmp-jdbc>   <enterprise-beans>     <entity>       <ejb-name>GangsterEJB</ejb-name>       <table-name>gangster</table-name>       <cmp-field>         <field-name>gangsterId</field-name>         <column-name>id</column-name>       </cmp-field>       <cmp-field>         <field-name>name</field-name>         <column-name>name</column-name>         <not-null/>       </cmp-field>       <cmp-field>         <field-name>nickName</field-name>         <column-name>nick_name</column-name>         <jdbc-type>VARCHAR</jdbc-type>         <sql-type>VARCHAR(64)</sql-type>       </cmp-field>       <cmp-field>         <field-name>badness</field-name>         <column-name>badness</column-name>       </cmp-field>     </entity>   </enterprise-beans> </jbosscmp-jdbc> 

The full content model of the cmp-field element of the jbosscmp-jdbc.xml is shown in Figure 11.4.

Figure 11.4. The JBoss entity element content model.


Detailed descriptions of the entity elements follow:

  • field-name This required element is the name of the cmp-field that is being configured. It must match the field-name element of a cmp-field declared for this entity in the ejb-jar.xml file.

  • read-only This element declares that the field in question is read-only. This field will not be written to the database by JBoss. Read-only fields are discussed later in this chapter.

  • read-only-timeout This is the time, in milliseconds, that a read-only field value will be considered valid.

  • column-name This optional element is the name of the column to which the cmp-field is mapped. The default is the field-name value.

  • not-null This optional element indicates that JBoss should add a NOT NULL to the end of the column declaration when automatically creating the table for this entity. The default for primary key fields and primitives is not null.

  • jdbc-type This is the JDBC type that is used when setting parameters in a JDBC prepared statement or loading data from a JDBC result set. The valid types are defined in java.sql.Types. This is required only if sql-type is specified. The default JDBC type is based on the database type in the datasource-mapping.

  • sql-type This is the SQL type that is used in CREATE TABLE statements for this field. Valid SQL types are limited only by your database vendor. This element is only required if jdbc-type is specified. The default SQL type is based on the database type in the datasource-mapping.

  • property This optional element allows you to define how the properties of a DVC CMP field should be mapped to the persistent store. This is discussed further later in this chapter.

  • auto-increment The presence of this optional field indicates that it is automatically incremented by the database layer. This is used to map a field to a generated column as well as to an externally manipulated column.

  • dbindex The presence of this optional field indicates that the server should create an index on the corresponding column in the database. The index name is fieldname_index.

  • check-dirty-after-get This value defaults to false for primitive types and the basic java.lang immutable wrappers (Integer, String, and so on). For potentially mutable objects, JBoss marks the field as potentially dirty after a get operation. If the dirty check on an object is too expensive, you can optimize it away by setting check-dirty-after-get to false.

  • state-factory This specifies the classname of a state factory object that can perform dirty checking for this field. State factory classes must implement the CMPFieldStateFactory interface.

Read-only Fields

JBoss allows you to have read-only CMP fields by setting the read-only and read-time-out elements in the cmp-field declaration. These elements work the same way as they do at the entity level. If a field is read-only, it will never be used in an INSERT or UPDATE statement. If a primary key field is read-only, the create method will throw a CreateException. If a set accessor is called for a read-only field, it throws an EJBException. Read-only fields are useful for fields that are filled in by database triggers, such as last update. A read-only CMP field declaration example follows:

 <jbosscmp-jdbc>     <enterprise-beans>         <entity>             <ejb-name>GangsterEJB</ejb-name>             <cmp-field>                 <field-name>lastUpdated</field-name>                 <read-only>true</read-only>                 <read-time-out>1000</read-time-out>             </cmp-field>         </entity>     </enterprise-beans> </jbosscmp-jdbc> 

Auditing Entity Access

The audit element of the entity section allows you to specify how access to an entity bean is audited. Auditing is allowed only when an entity bean is accessed under a security domain so that the caller identity is established. The content model of the audit element is shown in Figure 11.5.

Figure 11.5. The jbosscmp-jdbc.xml audit element content model.


The supported elements are as follows:

  • created-by This optional element indicates that the caller who created the entity should be saved to either the indicated column-name or CMP field-name.

  • created-time This optional element indicates that the time of entity creation should be saved to either the indicated column-name or CMP field-name.

  • updated-by This optional element indicates that the caller who last modified the entity should be saved to either the indicated column-name or CMP field-name.

  • updated-time This optional element indicates that the last time of entity modification should be saved to either the indicated column-name or CMP field-name.

For each element, if a field-name is given, the corresponding audit information should be stored in the specified CMP field of the entity bean being accessed. Note that there does not have to be a corresponding CMP field declared on the entity. If there are matching field names, you can access audit fields in the application by using the corresponding CMP field abstract getters and setters. Otherwise, the audit fields are created and added to the entity internally. You can access audit information in EJB-QL queries, using the audit field names but not directly through the entity accessors.

If, on the other hand, a column-name is specified, the corresponding audit information should be stored in the indicated column of the entity table. If JBoss is creating the table, you can use the jdbc-type and sql-type element to define the storage type.

The following code shows the declaration of audit information with given column names:

 <jbosscmp-jdbc>     <enterprise-beans>         <entity>             <ejb-name>AuditChangedNamesEJB</ejb-name>             <table-name>cmp2_audit_changednames</table-name>             <audit>                 <created-by>                     <column-name>createdby</column-name>                 </created-by>                 <created-time>                     <column-name>createdtime</column-name>                 </created-time>                 <updated-by>                     <column-name>updatedby</column-name></updated-by>                 <updated-time>                     <column-name>updatedtime</column-name>                 </updated-time>             </audit>         </entity>     </enterprise-beans> </jbosscmp-jdbc> 

Dependent Value Classes

Dependent value class (DVC) is a fancy term used to identity any Java class that is the type of a cmp-field and is not one of automatically recognized core types, such as strings and number values. By default, a DVC is serialized, and the serialized form is stored in a single database column. Although not discussed here, there are several known issues with the long-term storage of classes in serialized form.

JBoss also supports the storage of the internal data of a DVC in one or more columns. This storage is useful for supporting legacy JavaBeans and database structures. It is not uncommon to find a database with a highly flattened structure (for example, a PURCHASE_ORDER table with the fields SHIP_LINE1, SHIP_LINE2, SHIP_CITY, and so on, and an additional set of fields for the billing address). Other common database structures include telephone numbers with separate fields for area code, exchange, and extension and a person's name spread across several fields. With a DVC, multiple columns can be mapped to one logical field.

JBoss requires that a DVC to be mapped follow the JavaBeans naming specification for simple properties and that each property to be stored in the database have both a getter and a setter method. Furthermore, the bean must be serializable and must have a no-arg constructor. A property can be any simple type, and it can be an unmapped DVC or a mapped DVC, but it cannot be an EJB. A DVC mapping is specified in a dependent-value-class element within the dependent-value-classes element.

Figure 11.6 shows the structure jbosscmp-jdbc element.

Figure 11.6. The jbosscmp-jdbc dependent-value-class element model.


Here is an example of a simple ContactInfo DVC class:

 public class ContactInfo     implements Serializable {     /** The cell phone number. */     private PhoneNumber cell;     /** The pager number. */     private PhoneNumber pager;         /** The email address */     private String email;     /**      * Creates empty contact info.      */     public ContactInfo() {     }     public PhoneNumber getCell() {         return cell; }     public void setCell(PhoneNumber cell) {         this.cell = cell;     }     public PhoneNumber getPager() {         return pager;     }     public void setPager(PhoneNumber pager) {         this.pager = pager;     }     public String getEmail() {         return email;     }     public void setEmail(String email) {         this.email = email.toLowerCase();     }     // ... equals, hashCode, toString } 

The contact info includes a phone number, which is represented by another DVC class:

 public class PhoneNumber     implements Serializable {     /** The first three digits of the phone number. */     private short areaCode;       /** The middle three digits of the phone number. */         private short exchange;     /** The last four digits of the phone number. */         private short extension;     // ... getters and setters          // ... equals, hashCode, toString } 

The DVC mappings for these two classes are relatively straightforward:

 <dependent-value-classes>     <dependent-value-class>         <description>A phone number</description>         <class>org.jboss.cmp2.crimeportal.PhoneNumber</class>         <property>             <property-name>areaCode</property-name>             <column-name>area_code</column-name>         </property>         <property>             <property-name>exchange</property-name>             <column-name>exchange</column-name>         </property>         <property>             <property-name>extension</property-name>             <column-name>extension</column-name>         </property>     </dependent-value-class>     <dependent-value-class>         <description>General contact info</description>         <class>org.jboss.cmp2.crimeportal.ContactInfo</class>         <property>             <property-name>cell</property-name>             <column-name>cell</column-name>         </property>         <property>             <property-name>pager</property-name>             <column-name>pager</column-name>         </property>         <property>             <property-name>email</property-name>             <column-name>email</column-name>             <jdbc-type>VARCHAR</jdbc-type>             <sql-type>VARCHAR(128)</sql-type>         </property>     </dependent-value-class> </dependent-value-classes> 

Each DVC is declared with a dependent-value-class element. A DVC is identified by the Java class type declared in the class element. Each property to be persisted is declared with a property element. This specification is based on the cmp-field element, so it should be self-explanatory. (This restriction will be removed in a future release.) The current proposal involves storing the primary key fields in the case of a local entity and the entity handle in the case of a remote entity.

The dependent-value-class section defines the internal structure and default mapping of the classes. When JBoss encounters a field that has an unknown type, it searches the list of registered DVCs, and if a DVC is found, it persists that field into a set of columns; otherwise, the field is stored in serialized form in a single column. JBoss does not support inheritance of DVCs; therefore, this search is only based on the declared type of the field. A DVC can be constructed from other DVCs, so when JBoss runs into a DVC, it flattens the DVC tree structure into a set of columns. If JBoss finds a DVC circuit during startup, it throws an EJBException. The default column name of a property is the column name of the base cmp-field, followed by an underscore and then the column name of the property. If the property is a DVC, the process is repeated. For example, a cmp-field named info that uses the ContactInfo DVC would have the following columns:

 info_cell_area_code info_cell_exchange info_cell_extension info_pager_area_code info_pager_exchange info_pager_extension info_email 

The automatically generated column names can quickly become excessively long and awkward. You can override the default mappings of columns in the entity element, as follows:

 <jbosscmp-jdbc>     <enterprise-beans>         <entity>             <ejb-name>GangsterEJB</ejb-name>             <cmp-field>                 <field-name>contactInfo</field-name>                 <property>                     <property-name>cell.areaCode</property-name>                     <column-name>cell_area</column-name>                 </property>                 <property>                     <property-name>cell.exchange</property-name>                     <column-name>cell_exch</column-name>                 </property>                 <property>                     <property-name>cell.extension</property-name>                     <column-name>cell_ext</column-name>                 </property>                    <property>                     <property-name>pager.areaCode</property-name>                     <column-name>page_area</column-name>                 </property>                 <property>                     <property-name>pager.exchange</property-name>                     <column-name>page_exch</column-name>                 </property>                 <property>                     <property-name>pager.extension</property-name>                     <column-name>page_ext</column-name>                 </property>                 <property>                     <property-name>email</property-name>                     <column-name>email</column-name>                     <jdbc-type>VARCHAR</jdbc-type>                     <sql-type>VARCHAR(128)</sql-type>                 </property>             </cmp-field>         </entity>     </enterprise-beans> </jbosscmp-jdbc> 

When overriding property information for the entity, you need to refer to the property from a flat perspective, as in cell.areaCode.



JBoss 4. 0(c) The Official Guide
JBoss 4.0 - The Official Guide
ISBN: B003D7JU58
EAN: N/A
Year: 2006
Pages: 137

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net