Variations on ADF BC isAttributeChanged method

ADF Business Components have a method isAttributeChanged available in Entity Objects that returns true if the the attribute has been changed since it was obtained from the Database. This method can cause a problem when used in business rules that are triggered at Commit time, or in business rules that only apply when the attribute value has actually changed.

Problem when calling isAttributeChanged at Commit time

From the Javadoc of EntityImpl: Note that if a Posting operation is performed, and the attribute value is sync'd with the database, that subsequent requests will return false, until the next time the attribute is changed.

As Jan Kettenis pointed out, this means that if you use isAttributeChanged for a business rule that is triggered at Commit time, it will always return false, even though the attribute was changed. Jan describes a workaround for this problem.

Problem calling isAttributeChanged if value changed back to old value

Another quote from the Javadoc of EntityImpl: Note that this method will return true if the value has been set to the same as the database value since it doesn't perform a value comparison.

This can be a problem for validations that apply only when the value changes: for example, the rule "Department Name cannot be changed if the Department has Employees". You might have implemented the rule in a method validator using isAttributeChanged:

  return (!isAttributeChanged(DEPARTMENTNAME) || !hasEmployees());

Suppose a Department has Employees, and you change both the Department Name and the Department Manager. When you apply these changes, you obviously get an error because you are not allowed to change the Department Name. Suppose you now change the Department Name back to its original value, and try again, because you still want to change the Department Manager. You will still get the error, because isAttributeChanged(DEPARTMENTNAME) will remain false until you have posted the data, even though the attribute value is now the same as the value in the database!

To avoid this, you can define a variation on isAttributeChanged in your EntityImpl base class: isAttributeValueChanged (but note that when called from Commit level, it will still return false like Jan described).

  /**
* Using getPostedAttribute and getAttribute this method retrieves the old and new
* values and compares whether it has changed. Alternative to isAttributeChanged,
* which returns true if the value was modified to the same value as the database.
* @param index index of the attribute.
* @return true if the value of the attribute at the given index
* is different from the one in the database.
*/
public boolean isAttributeValueChanged(int index) {
Object oldVal = getPostedAttribute(index);
Object newVal = getAttribute(index);
boolean valueChanged = true;
if ((oldVal == null) && (newVal == null)) {
valueChanged = false;
} else if (newVal != null) {
if (newVal instanceof String) {
if (((String)newVal).length() == 0) {
if (oldVal == null) {
valueChanged = false;
}
}
}
if (valueChanged && newVal.equals(oldVal)) {
// in new rows, the oldVal is always the same as the newVal,
// but if the value is not null in a new row, we want to return true
if (getEntityState() != Entity.STATUS_NEW) {
valueChanged = false;
}
}
}
return valueChanged;
}

Comments:

I have updated the code example to check for Entity.STATUS_NEW, so that the method also works in new rows.

Posted by Sandra Muller on February 09, 2009 at 09:01 PM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Java EE Consultants - JHeadstart, ADF, JSF

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today