This discussion is archived
5 Replies Latest reply: Feb 24, 2012 8:20 AM by cdelahun RSS

Toplink: Multiple Transcation using same UnitofWork with Locking Policy

583687 Newbie
Currently Being Moderated
Hello,

Is it possible to update 2 separate instances of same Toplink object in One Transaction? Like updating Employee1 & Employee2 objects using same UnitofWork object.
I am getting exception when trying to do. I start the transaction and write the Employee1 object and then without committing these changes I am trying to write the Employee2 object. I want to do it in same Transaction. When I am trying to do so, it throws the OptimisticLockException,

Before writing the object, I am checking if the object is modified before writing so that appropriate message can be thrown. I am using version number to check the modification. They seems ok.

Exception Trace -
*An attempt was made to update the object [ Employee = ........... ] , but it has no version number in the identity map.*
It may not have been read before the update was attempted.
at oracle.toplink.exceptions.OptimisticLockException.noVersionNumberWhenUpdating(OptimisticLockException.java:102)
     at oracle.toplink.descriptors.VersionLockingPolicy.addLockValuesToTranslationRow(VersionLockingPolicy.java:98)
     at oracle.toplink.internal.queryframework.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1115)
     at oracle.toplink.queryframework.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:69)
     at oracle.toplink.internal.queryframework.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:279)
     at oracle.toplink.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:47)
     at oracle.toplink.queryframework.DatabaseQuery.execute(DatabaseQuery.java:671)
     at oracle.toplink.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:594)
     at oracle.toplink.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:103)
     at oracle.toplink.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:75)
     at oracle.toplink.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2697)
     at oracle.toplink.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1074)
     at oracle.toplink.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1058)
     at oracle.toplink.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1017)
     at oracle.toplink.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:285)
     at oracle.toplink.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:217)
     at oracle.toplink.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:174)
     at oracle.toplink.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3441)
     at oracle.toplink.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1322)
     at oracle.toplink.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1414)
     at oracle.toplink.internal.sessions.UnitOfWorkImpl.writeChanges(UnitOfWorkImpl.java:5066)

The exception it shows is related to Employee1 object. But I am updating the Employee2 object. I checked the IdentityMap, the Version number is present for the object. I tried to read the object explicitly before writing the changes. I tried updating IdentityMap. Both option didnt work.
I have to commit the changes for Employee1 object and then start new transaction to write Employee2 object.

Any Idea why it could be happening?
  • 1. Re: Toplink: Multiple Transcation using same UnitofWork with Locking Policy
    cdelahun Pro
    Currently Being Moderated
    Sorry, can you explain what you mean by two instances in one transaction? Do you mean different instances of the same data, or two Employee objects that have different IDs? Do you get the exception if you attempt to write a single object?

    The problem depends on how you are registering the objects with the UnitOfWork - if they are existing you should read them in through the UnitOfWork first so that the version number etc are populated. If your instance isn't the working copy from the unitofwork, you'll then need to merge your changes into the working copy.

    Best Regards,
    Chris
  • 2. Re: Toplink: Multiple Transcation using same UnitofWork with Locking Policy
    583687 Newbie
    Currently Being Moderated
    I mean Different instances of the same data - Like 2 separate instances of Employee class. I don't get any exception while writing single object. Its the issue when I am trying to use the single Transaction Container (UnitofWork) object to write 2 objects.

    Same way I am able to write 2 separate instances of 2 separate class without any issue using same UnitofWork.

    I tried to read the objects before writing them using same UnitofWork. Same way I tried to update the IdentityMap but that also didn't work.

    Is this possible to write 2 separate instances of objects of same class using same UnitofWork?
  • 3. Re: Toplink: Multiple Transcation using same UnitofWork with Locking Policy
    cdelahun Pro
    Currently Being Moderated
    I'm still not sure I follow how you are updating or using the UnitOfWork. What api are you using, and how are you registering these objects?

    A unitofwork registers an object and creates a working copy of it for tracking changes. There is only one workingcopy whose changes are picked up and persisted into the database. Any changes you have to other instances will need to be merged into the working copy.

    Please see
    http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#Merging_Changes_in_Working_Copy_Clones
    for advanced api usage and merging in serialized copies into the workingclone. For general UnitOfWork information, see
    http://wiki.eclipse.org/Introduction_to_EclipseLink_Transactions_(ELUG)
    and http://wiki.eclipse.org/Using_Basic_Unit_of_Work_API_%28ELUG%29

    Best Regards,
    Chris
  • 4. Re: Toplink: Multiple Transcation using same UnitofWork with Locking Policy
    583687 Newbie
    Currently Being Moderated
    I am calling below API to write data,

    public void writeChanges(Object obj) {

    UnitOfWork uow = getUnitOfWork();
    -- uow.beginEarlyTransaction(); // This call me made when getUnitofWork is called while reading the data before calling writeChanges method. I am holding the same UnitofWork .

    obj= uow.mergeClone(obj);
    if (uow.hasChanges()) {
    uow.forceUpdateToVersionField(obj, false);
    }
    uow.writeChanges();

    }

    The Object is read using the same UnitofWork object. I am calling readObject(obj) method to read the object.

    Edited by: Sujay Patil on Feb 24, 2012 9:38 PM
  • 5. Re: Toplink: Multiple Transcation using same UnitofWork with Locking Policy
    cdelahun Pro
    Currently Being Moderated
    The merge seems corrrect, but not the writeChanges. The javadoc for writeChanges states: "Can only be called once. It can not be used to write out changes in an incremental fashion."
    So you cannot call this code multiple times. Try removing the writeChanges so that the objects are writen out only once at commit time.

    Best Regards,
    Chris

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points