To borrow a phrase from Jim Frentress:
Tuned Update - the process of persisting only the EJB fields that have
changed.
I suppose most well-behaved containers will use tuned updates within their
CMP infrastructure. My current container does, and it helps a great deal to
eliminate the concurrency issues associated with one user wiping out a
change made by a previous user.
This, of course, does nothing to assist me in BMP. I have to manage this
concurrency issue myself. My EJB structure follows the segregated design
fundamentals discussed in earlier threads. All of my EJB's extend an EJB
superclass. Would it make sense to use reflection and a hashtable in this
superclass to store the pre-write state of an EJB? When a write occurs, I
can then compare the current attributes against the hash to determine what
fields to write.
I had a similar mechanism in my RMI objects, although it stored any
attributes with a getter:
/** Analyzes the current object and stores the current state of the
* object in a hashtable. The hashtable will store all attributes
* of the instance class and its ancestors. Only attributes with a
* corresponding getXXX() method (and no parameters) will be
* stored.
*/
public void mirror() {
hash.clear();
Class myClass = this.getClass();
Method[] methods = myClass.getMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
String name = method.getName();
Class[] parameters = method.getParameterTypes();
if (name.startsWith("get") && parameters.length == 0) {
Class returnType = method.getReturnType();
try {
Object o = method.invoke(this, null);
if (o != null) hash.put(name, o);
}
catch (InvocationTargetException itx) {/*shouldn't ever
happen*/}
catch (IllegalAccessException iax) {/*shouldn't ever happen*
/}
}
}
}
I then could get a list of attributes that changed by using:
/** Returns whether the named method is modified. Useful for detecting
* a change to a specific attribute. If the attribute has changed
* a Vector is returned that contains the previous and current values:
*
* [0] - The value of the attribute stored in the hash
* [1] - The class instance's current value for the attribute
*
* If no changes are detected the return value will be null.
*/
public boolean isModified(String methodName, final Object[] values) {
values[0] = null; values[1] = null;
Class myClass = this.getClass();
Method[] methods = myClass.getMethods();
Object o1= hash.get(methodName);
for (int i = 0; i < methods.length; i++) {
String name = methods[i].getName();
if (name.equalsIgnoreCase(methodName)) {
Object o2 = null;
try {
o2 = methods[i].invoke(this, null);
}
catch (InvocationTargetException itx2) {}
catch (IllegalAccessException iax2) {}
if (o1 == null) {
if (o2 != null) {
values[1] = o2;
return true;
}
continue;
}
if (!o1.equals(o2)) {
log("Is modified on method: " + name);
log("Stored value: " + o1 + ", Instance value: " + o2);
values[0] = o1;
values[1] = o2;
return true;
}
}
}
return false;
}
Basically, you would call mirror() in the ejbLoad() method, and use the
isModified() to determine which fields you add to your update query in the
ejbStore() method.
Has anyone come across this situation?
jim
===========================================================================
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".