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]>
