Hi,

This is the email I said I would send yesterday.  I am will attempt to
explain how to turn on the new features in CMP 2.x

1. Specify the ejb-jar.xml to validate with the EJB 2.0 DTD. Change the
doctype in your current ejb-jar.xml to the following:

<!DOCTYPE jar-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 2.0//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd";>

This will activate the new persistence store, and turn on the first two
features CMP 2.x abstract accessors and Tuned updates.  Tuned updates are
now always on; this is a side affect of eager/lazy loading.

2. Add a jbosscmp-jdbc.xml to the META-INF directory of your jar. The format
is similar to jaws.xml, with one major change around finder specification.
Everything else is new, so just build one according to the jaws docs.

3. Eager loading:  The new <eager-load> element is declared after your
<cmp-field> elements in the <entity> section. Eager load tells the store
manager which fields to load when loading your bean from the database.  In
CMP 1.x every field in the bean was eager loaded, and this is the default if
eager-load is not specified. The XML follows:

<eager-load>
 <field-name>title</field-name>
 <field-name>artist</field-name>
</eager-load>

This tells the manager to only load the title and artist fields.  In
addition to these two fields, the manager always loads the primary key
fields. If you would like to not eager-load any fields, just specify an
empty <eager-load> element. In the future I plan on adding a similar section
to the query metadata.

3. Lazy load groups:  Lazy loading is the other half of eager loading.  If a
field is not eager loaded it must be lazy loaded. I have added the concept
of what I am calling lazy load groups (I'm considering changing it to sets).
When the bean code accesses an unloaded field, the manager loads the field
and any field in a group that the unloaded field is a member.  Think of the
groups as a set. The manager performs a set join and then removes any field
that is already loaded. The lazy-load-groups element should follow the
<eager-load> element in the <entity>. An example follows:

<lazy-load-groups>
 <lazy-load-group>
  <field-name>type</field-name>
  <field-name>notes</field-name>
 </lazy-load-group>
 <lazy-load-group>
  <field-name>notes</field-name>
  <field-name>producer</field-name>
 </lazy-load-group>
</lazy-load-groups>

If the bean code accesses type, the manager loads type and notes. If the
bean code accesses, notes the manager will load notes, type and producer.

4. Read-only columns: <cmp-field> element can now contain then <read-only>
and <time-out> elements. These elements work the same way as they do in the
<entity> tag.  If a field is read-only, it will not be stored or inserted
into the database. If a pk field is read-only, bean create will throw a
CreateException. If a set accessor is called for a read-only field, it
throws an EJBException.  Read-only fields are important for fields that are
filled in by database triggers, such as last update.

5. Dependent value classes: DVCs are just cmp fields that have a java object
type, other then the automatically recognized types. This comes from section
10.3.3 of EJB2.0 pfd2. The specification specifically does not describe the
internal structure of the object.  I require that DVCs follow the Java Beans
naming specification for getters and setters.  Each property you would like
saved to the database must have both a getter and a setter.  The bean must
be serializable and must have a no-arg constructor.  These requirements
extend to all properties that will be saved.

Ok, now we have a valid DVC. All we need to do is tell the manager about it.
The DVC is specified in the jbosscmp-jdbc.xml file as follows:

<dependent-value-classes>
 <dependent-value-class>
  <description>address information</description>
  <class>com.hypothermic.example.cd.Address</class>
  <property>
   <property-name>line1</property-name>
   <column-name>LINE1</column-name>
  </property>
  <property>
   <property-name>line2</property-name>
   <column-name>LINE2</column-name>
  </property>
  <property>
   <property-name>city</property-name>
   <column-name>CITY</column-name>
  </property>
  <property>
   <property-name>state</property-name>
   <column-name>ST</column-name>
   <jdbc-type>VARCHAR</jdbc-type>
   <sql-type>VARCHAR(2)</sql-type>
  </property>
  <property>
   <property-name>zip</property-name>
  </property>
  <property>
   <property-name>zipPlusFour</property-name>
   <column-name>ZIP_4</column-name>
  </property>
 </dependent-value-class>
 <dependent-value-class>
  <description>Credit Card</description>
  <class>com.hypothermic.example.cd.Card</class>
  <property>
   <property-name>cardHolder</property-name>
   <column-name>CARD_HOLDER</column-name>
  </property>
  <property>
   <property-name>billingAddress</property-name>
   <column-name>ADD</column-name>
  </property>
  <property>
   <property-name>cardNumber</property-name>
   <column-name>CARD_NUMBER</column-name>
  </property>
 </dependent-value-class>
</dependent-value-classes>

This section should appear after the <enterprise-beans> element.  The
specification is based on the <entity> element, so it should be
self-explanatory.

When the manager encounters a field that has the type of a specified DVC, it
will persist this field to the columns specified. DVCs can be constructed
from other DVCs, so when the manager runs into a DVC it flattens it into a
set of columns. If the manager finds a DVC circuit, it will throw an
EJBException. Property mappings can be overridden in the entity element as
follows:

<entity>
 <name-name>CustomerBean</name-name>
 <table-name>CUSTOMER</table-name>
 <cmp-field>
  <field-name>userId</field-name>
  <column-name>USER_ID</column-name>
 </cmp-field>
 <cmp-field>
  <field-name>creditCard</field-name>
  <column-name>CREDIT_CARD</column-name>
  <property>
   <property-name>cardNumber</property-name>
   <column-name>CC_NUM</column-name>
   <jdbc-type>VARCHAR</jdbc-type>
   <sql-type>VARCHAR(20)</sql-type>
  </property>
  <property>
   <property-name>billingAddress.line1</property-name>
   <column-name>ADDRESS_LINE1</column-name>
  </property>
 </cmp-field>
</entity>

Pretty simple right?  The only thing to note is the billingAddress.line1.
When overriding property info in the entity, you need to refer to the
property from a flat perspective.

6. Finder specification:  I have changed the specification of finders to
bring them more in line with ejb-ql.  Here is an example finder:


<query>
 <description>Search all fields in cd</description>
 <query-method>
  <method-name>findInAnyField</method-name>
  <method-params>
   <method-param>java.lang.String</method-param>
  </method-params>
 </query-method>
 <declared-sql>
  <where>TITLE={0} OR ARTIST={0} OR TYPE={0} OR NOTES={0}</where>
 </declared-sql>
</query>


The query-method element is right out of the EJB 2.0 spec. The
<declared-sql> element is similar to jaws finder element, except I have
broken the query element into from and where. I also support order as jaws
did.  The new code doesn't have the new pre-load logic, but I will add
something similar in phase 3, where I'll add ejb-ql support.



I hope someone tries the new cmp code, as I haven't had time to do a
complete test.  I have a limited unit test that I can send anyone interested
(just send me a personal email). I will write a complete test in phase 4.

If you find any bugs or would like to request a feature, please email me. I
will fix bugs as they are discovered, and feature req1uests I will
definitely think over.

Dain Sundstrom



_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to