Object temp;
int fieldType;
AccessMode accessMode = getAccessMode( suggestedAccessMode );
if ( oid.getIdentity() == null )
throw new PersistenceException("The identities of the object to be loaded is null");
// load the fields from the persistent storage if the cache is empty
// and the accessMode is readOnly.
fields = (Object[]) locker.getObject( tx );
if ( fields == null || accessMode == AccessMode.DbLocked ) {
fields = new Object[_fhs.length];
if( results != null ) {
stamp = results.getQuery().fetch( fields, oid.getIdentity() );
} else {
conn = (Connection)tx.getConnection(oid.getLockEngine());
stamp = _persistence.load( conn, fields, oid.getIdentity(), accessMode );
}
oid.setDbLock( accessMode == AccessMode.DbLocked );
locker.setObject( tx, fields );
}
// set the timeStamp of the data object to locker's timestamp
if ( object instanceof TimeStampable ) {
((TimeStampable)object).jdoSetTimeStamp( locker.getTimeStamp() );
}
// set the identities into the target object
ids = oid.getIdentity();
setIdentity( tx, object, ids );
// iterates thur all the field of the object and bind all field.
for ( int i = 0; i < _fhs.length; i++ ) {
fieldType = _fhs[i].getFieldType();
switch (fieldType) {
case FieldMolder.PRIMITIVE:
// simply set the corresponding Persistent field value into the object
temp = fields[i];
if ( temp != null )
_fhs[i].setValue( object, temp, tx.getClassLoader() );
else
_fhs[i].setValue( object, null, tx.getClassLoader() );
break;
case FieldMolder.SERIALIZABLE:
// deserialize byte[] into java object
try {
byte[] bytes = (byte[]) fields[i];
if ( bytes != null ) {
// The following code can be updated, after Blob-->InputStream
// to enhance performance.
ByteArrayInputStream bis = new ByteArrayInputStream( bytes );
ObjectInputStream os = new ObjectInputStream( bis );
Object o = os.readObject();
_fhs[i].setValue( object, o, tx.getClassLoader() );
} else {
_fhs[i].setValue( object, null, tx.getClassLoader() );
}
} catch ( OptionalDataException e ) {
throw new PersistenceException( "Error while deserializing an dependent object", e );
} catch ( ClassNotFoundException e ) {
throw new PersistenceException( "Error while deserializing an dependent object", e );
} catch ( IOException e ) {
throw new PersistenceException( "Error while deserializing an dependent object", e );
}
break;
case FieldMolder.PERSISTANCECAPABLE:
// field is not primitive type. Related object will be loaded
// thru the transaction in action if needed.
fieldClassMolder = _fhs[i].getFieldClassMolder();
fieldEngine = _fhs[i].getFieldLockEngine();
if ( fields[i] != null ) {
// use the corresponding Persistent fields as the identity,
// and we ask transactionContext in action to load it.
try {
// should I use lazy loading for this object?
if (_fhs[i].isLazy()) {
temp = SingleProxy.getProxy(tx, fieldEngine, fieldClassMolder, fields[i], null, suggestedAccessMode);
} else {
temp = tx.load(fieldEngine, fieldClassMolder, fields[i], null, suggestedAccessMode);
}
} catch (ObjectNotFoundException ex) {
temp = null;
}
_fhs[i].setValue( object, temp, tx.getClassLoader() );
} else {
_fhs[i].setValue( object, null, tx.getClassLoader() );
}
break;
case FieldMolder.ONE_TO_MANY:
case FieldMolder.MANY_TO_MANY:
// field is one-to-many and many-to-many type. All the related
// object will be loaded and put in a Collection. And, the
// collection will be set as the field.
fieldClassMolder = _fhs[i].getFieldClassMolder();
fieldEngine = _fhs[i].getFieldLockEngine();
if ( !_fhs[i].isLazy() ) {
// lazy loading is not specified, load all objects into
// the collection and set the Collection as the data object
// field.
ArrayList v = (ArrayList)fields[i];
if ( v != null ) {
// simple array type support
Class collectionType = _fhs[i].getCollectionType();
if (collectionType.isArray()) {
Object[] value = (Object[])java.lang.reflect.Array.newInstance(
collectionType.getComponentType(), v.size());
for ( int j=0,l=v.size(); j<l; j++ ) {
value[j] = tx.load( oid.getLockEngine(), fieldClassMolder, v.get(j), null, suggestedAccessMode );
}
_fhs[i].setValue( object, value, tx.getClassLoader() );
} else {
CollectionProxy cp = CollectionProxy.create( _fhs[i], object, tx.getClassLoader() );
for ( int j=0,l=v.size(); j<l; j++ ) {
cp.add( v.get(j), tx.load( oid.getLockEngine(), fieldClassMolder, v.get(j), null, suggestedAccessMode ) );
}
cp.close();
//_fhs[i].setValue( object, cp.getCollection() );
}
} else {
_fhs[i].setValue( object, null, tx.getClassLoader() );
}
} else {
// lazy loading is specified. Related object will not be loaded.
// A lazy collection with all the identity of the related object
// will constructed and set as the data object's field.
ArrayList list = (ArrayList) fields[i];
RelationCollection relcol = new RelationCollection( tx, oid, fieldEngine, fieldClassMolder, accessMode, list );
_fhs[i].setValue( object, relcol, tx.getClassLoader() );
}
break;
default:
throw new PersistenceException("Unexpected field type!");
}
}
return stamp;
}