Exception + Bugfix(?): could not load field value with comm
hmartin Jul 29, 2004 9:02 AMHello,
we have developed a J2EE Application (5 SLSB's, 25 EB) which is running with JBOSS 3.2.5 and JDK 1.4.2_04 under a Windows environment. We are using CMP 2.x with CMR. The Database is Oracle 9i. Our EJB-Container uses commit option A (not clustered).
With this configuration we get sometimes (!) but not allways the Exception
could not load field value ... when we traverse the entities in a relationship and try to access the fields of one entity from the collection.
I know that there was a bug like this in version 3.2.4 but this should be already fixed (jboss-Bugs-978763).
After fixing the code everything works fine. Can please someone look at the fix if i am right or if i have only too less sleep.
Fixed file: jboss-3.2.5src\server\src\main\org\jboss\ejb\plugins\cmp\jdbc\JDBCCMP2xFieldBridge.java
Mehod: getInstanceValue
Original
public Object getInstanceValue(EntityEnterpriseContext ctx) { // notify optimistic lock FieldState fieldState = getFieldState(ctx); if(!fieldState.isLoaded()) { manager.loadField(this, ctx); if(!fieldState.isLoaded()) throw new EJBException("Could not load field value: " + getFieldName()); } return fieldState.getValue(); }
Patch:
public Object getInstanceValue(EntityEnterpriseContext ctx) { // notify optimistic lock FieldState fieldState = getFieldState(ctx); if(!fieldState.isLoaded()) { manager.loadField(this, ctx); if(!fieldState.isLoaded()) { fieldState = getFieldState(ctx); if(!fieldState.isLoaded()) { throw new EJBException("Could not load field value: " + getFieldName()); } } } return fieldState.getValue(); }
Description:
In the method above you make
FieldState fieldState = getFieldState(ctx);. The method getFieldState creates, if the condition is true a new Object FieldState. Later comes the call
manager.loadField(this, ctx);. This method bind the cache to the context and looks if the field is already loaded. If not it loads the field from the database. The problem seems to be the check in the loadField method because this method call getFieldState implicitly again and also possible creates a new (!) FieldState instance to test if the field is loaded. After
manager.loadField(this, ctx);there is a call
if(!fieldState.isLoaded()) { ...but here to the possible other old instance from FieldState. So it can be that the value is loaded but an Exception will be thrown.