All right, I've got this CMP pattern which keeps recurring. If this is
common say so, but I haven't seen others' solutions to it. I've got a few
proposed solutions and would like feedback. I'm working in VisualAge for
Java 3.5.2.

Beware before you send suggestions -- using BMP is NOT an option here. I
need a CMP solution.

The problem occurs when there are two CMP entity beans in a 1-many
relationship and a CMP attribute in one bean is dependent on the other
bean's attribute(s) or number of instances. For example (this is ONLY an
example to illustrate the concept by analogy), Employer and Employee are in
a 1-many relationship, and Employer has persistent attributes numEmployees
and totalEmployeeSalaries.

Now use these definitions for the calculated attributes in Employer:
numEmployees = number of employees linked to this employer
totalEmployeeSalaries = sum of salaries for all employees linked to this
employer.

Here are some solutions regarding these attributes and what I see as their
pros and cons:
---------------------
1) Remove setter methods from Employer's remote interface. Make the getter
methods in Employer actually calculate their values each time they're
called.

pro:
-attribute values are always "correct" in EJB space when Employer's getter
methods are called

cons:
-wastefully slow computations and loads when there are many Employees. If
there are thousands of employees, every time getTotalEmployeeSalaries() is
called on Employer ALL fields of ALL the corresponding Employees must be
retrieved from the database, adding only ONE of the retrieved fields for
salary to the sum, and discarding everything else.
-attribute values can be wrong in the database. If an employee's salary
changes (using either its EJB remote interface or directly using SQL), the
employer's totalEmployeeSalaries field is not automatically updated. If an
employee is added or removed, the employer's numEmployees field is not
automatically updated. If reporting is being done using SQL, the reported
values are not guaranteed correct.

---------------------
2) Remove setter methods from Employer's remote interface. Introduce
corresponding changeXXX() methods for the attributes, like
changeNumEmployees( int change ) and changeTotalEmployeeSalaries( BigDecimal
change ) on the remote interface. In Employee, call changeNumEmployees( 1 )
and changeTotalEmployeeSalaries( mySalary ) on the Employer during
ejbPostCreate(). Call changeNumEmployees( -1 ) and
changeTotalEmployeeSalaries( mySalary.negate() ) on the Employer during
ejbRemove(). During Employee's setMySalary(newSalary), call
changeTotalEmployeeSalaries( newSalary.subtract(oldSalary) ) on the
Employer.

pro:
-faster getter methods on Employer since values already calculated. Provided
ALL access to these fields is through the EJBs the values should always be
correct.

cons:
-changeXXX methods on Employer's remote interface should ONLY be called by
Employee. Do I have to set up roles to guarantee this restriction? Otherwise
any EJB (even a session bean) could call Employer's changeXXX methods and
Employer's values would be incorrect from that point forward.
-once the attribute values are wrong in the database (say, someone uses SQL
to alter the value directly in the database) then they are never
recalculated so they will be wrong from that point forward.

---------------------
3) Leave the setter methods on Employer's remote interface and do not
perform any computations for the getter methods. Leave it up to external
processes (Session Beans) to update the fields correctly.

pro:
-simple Entity Bean design; set and get the fields and persist them. No
computation involved.

con:
-Very Highly Likely that the attributes will be wrong if Session Bean
designers forget to update these fields explicitly every time a change to an
Employee occurs.

---------------------
4) Remove setter methods from Employer's remote interface; put triggers in
the database to perform the calculations.

pro:
-database integrity guaranteed

con:
-lack of portability due to syntax of trigger language and inability to
"export the schema" of the EJBs to another database and have the EJBs work
immediately without significant database modification.
-If the Employer has already been retrieved in the current transaction and
an Employee's salary is changed, the trigger changes the database column for
the Employer at the END of the EJB transaction, so calling a getter method
on Employer before the EJB transaction ends will not give the updated value.
-for VERY large numbers of Employees, the recalculation implied by the
trigger will become slow.

---------------------
Charles May, Software Engineer
AFCO Credit/Mellon Financial Corp
phone: (412) 234-8436
email: mailto:[EMAIL PROTECTED]

The views expressed in this message are my own, and do not necessarily
represent the views of my employer.

*****************************************************************
DISCLAIMER:   The information contained in this e-mail may be confidential
and is intended solely for the use of the named addressee.  Access, copying
or re-use of the e-mail or any information contained therein by any other
person is not authorized.  If you are not the intended recipient please
notify us immediately by returning the e-mail to the originator.

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to