Hi all,

If I want to modify an object outside of a transaction (e.g. on a remote client and I'm not using ojb c/s mode) and then apply the changes to the db, I think there is a limitation with the current ObjectEnvelopeTable handling. Here is an outline of what I want to do: bigGraph is an A reference to a (possibly large) persistent graph of objects:

void lifeOfA() {
// find the object
transaction=odmg.newTransaction();
transaction.begin();
A myA = findAById(SOME_ID);
transaction.commit();

// modify myA's bigGraph (perhaps in a different VM)
...

// update myA's bigGraph
transaction=odmg.newTransaction();
transaction.begin();
A oldMyA = findMyA(SOME_ID);
oldMyA.setBigGraph(myA.getBigGraph()); // replace a referenced graph
transaction.lock(oldMyA.getBigGraph(), Transaction.WRITE);
transaction.commit();
}

A findAById(long theId) {
OQLQuery aQuery=odmg.newOQLQuery();
aQuery.create("select a from com.acme.A where id == " + theId);
result = (DList)aQuery.execute();
return (A)result.next();
}


The original contents of oldMyA's bigGraph are placed on the ObjectEnvelopeTable within findAById. Any db update need only apply to the nodes of bigGraph that have truly been modified. The call

transaction.lock(oldMyA.getBigGraph(), Transaction.WRITE);

calls Transaction.register() on the base object of the bigGraph, but the new state of the object (assuming its Identity is constant) never affects the objectEnvelopeTable and therefore the subsequent modification check in Transaction.commit()

if (mod.hasChanged())

always returns false, and no db update occurs.

As a possible remedy, I changed Transaction.register() to force a changed to the ObjectEnvelopeTable if a write lock is required:

// no Proxy:
ObjectEnvelope envelope = objectEnvelopeTable.getByIdentity(new Identity(objectToRegister, getBroker()));
if ((envelope == null) || envelope.needsDelete())
{
...
}
else
{
// Object already registered, do nothing!
// Instead of doing nothing...
if (lockMode == Transaction.WRITE && objectToRegister != envelope.getObject())
{
envelope.setObj(objectToRegister);
if (useImplicitLocking)
{
ClassDescriptor cld = null;
cld = this.getBroker().getClassDescriptor(objectToRegister.getClass());
lockReferences(cld, objectToRegister, lockMode);
lockCollections(cld, objectToRegister, lockMode);
}
}
}


This did what I wanted, but I am unsure about the bigger implications of this change (e.g. if the updated graph is smaller, deletions are not considered).

Could someone please comment or suggest a nicer way to do the same thing?


Thanks,

Phil


--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to