Skip to Main Content

Integration

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

backupCloneIsOriginalFromParent Exception

426437Apr 28 2005 — edited Feb 28 2007
Argh, we got this incredible showstopper:

Using OracleAS TopLink - 10g (9.0.4.5) (Build 040930) and the Spring Integration.

1. Use the PlatFormTransactionManager to get a transaction and transactionstatus.
2. Read a collection of objects from the database using TopLinkCallback and session.executeQuery
3. Register all objects in the collection with session.getActiveUnitOfWork().registerAllObjects(collection)
4. Return the collection that is the result of registerAllObjects() (the clones)
5. Modify the registered objects
6. Commit the transaction

This results in the following:
Exception [TOPLINK-6004] (OracleAS TopLink - 10g (9.0.4.5) (Build 040930)): oracle.toplink.exceptions.QueryException
Exception Description: The object [model.value.external.tachonet.db.MsToTcnRequestMessage@18df2e4], of class [class value.external.tachonet.db.MsToTcnRequestMessage], with identity hashcode (System.identityHashCode()) [26,079,972],
is not from this UnitOfWork object space, but the parent session's. The object was never registered in this UnitOfWork,
but read from the parent session and related to an object registered in the UnitOfWork. Ensure that you are correctly
registering your objects. If you are still having problems, you can use the UnitOfWork.validateObjectSpace() method to
help debug where the error occurred. For more information, see the manual or FAQ.
at oracle.toplink.exceptions.QueryException.backupCloneIsOriginalFromParent(QueryException.java:153)
at oracle.toplink.publicinterface.UnitOfWork.getBackupClone(UnitOfWork.java:1536)
at oracle.toplink.publicinterface.UnitOfWork.calculateChanges(UnitOfWork.java:438)
at oracle.toplink.publicinterface.UnitOfWork.commitToDatabaseWithChangeSet(UnitOfWork.java:1135)
at oracle.toplink.publicinterface.UnitOfWork.commitRootUnitOfWork(UnitOfWork.java:956)
at oracle.toplink.publicinterface.UnitOfWork.commit(UnitOfWork.java:771)
at org.springframework.orm.toplink.TopLinkTransactionManager.doCommit(Unknown Source)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:401)
at services.gateway.TACHOnetServiceImpl.sendBatchMessage(TACHOnetServiceImpl.java:751)
at services.gateway.TACHOnetServiceImpl.sendBatchMessages(TACHOnetServiceImpl.java:827)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:221)
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:165)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:191)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:516)

This even occurs when I don't modify the objects, just commit at the end! Does anyone have ANY idea what the cause of this can be? This is a real showstopper for us. :(

The collection retrieved above also has relations to other objects. I suspect the error occurs because we don't clone them to, but how do you do this when there are heaps of relations? Should I clone each separate and assign it back to the first clone? The relations are already there before cloning, I shouldn't have to maintain them should I?

Regards,
Anders,

Comments

426437 Apr 28 2005
And doing uow.dontPerformValidation() "fixes" the problem. It's probably not a good solution, and I'm a bit sceptical about how it effects our cache, but it lets us move on for now. Any idea?

Anders,
Donald Smith-Oracle Apr 28 2005
You are correct to be nervous about your work around, but if it keeps the development going, then I'm glad it works.

Based on experience, I am highly confident that somewhere in your code, you are (accidentally) hooking up a session object to a UOW clone.

Perhaps a quick read through of the UOW primer will help spot where this might be happening:

www.oracle.com/technology/products/ ias/toplink/technical/unitOfWorkWP.pdf

By the way, here is some good news for the future: these issues are soon to be obsolete. I'm in some training this week with our next generation of TopLink based around the EJB3 standard. Thank's to some neat tech, TopLink is able to figure out on the fly what you are doing to an object and will automatically make sure that you always have the right object for the context, without having to jump through hoops. Of course, I'm "old school" and will probably keep to the "old way", but the new way is sure to please. Keep your eye out for the next preview release on OTN...

- Don
Jamclark-Oracle Apr 28 2005
How do you query for the value.external.tachonet.db.MsToTcnRequestMessage instance (the one that's causing the Exception)? Normally, this Exception occurs when the MsToTcnRequestMessage instance comes from a query against the Session (not the UnitOfWork) and is then related to a "registered" Object.

It sounds, from your description, like you've been careful to insure that this doesn't happen but is there any way that one of your registered clones could've become related to an existing, but unregistered instance?


426437 Apr 28 2005
I can't see how any non registered objects can be tied in there. This is the following code I'm using to retrieve and register the objects. When calling uow.validateObjectSpace() it throws the exception right after registration, before anything has a chance to alter the objects.

public Collection getCountryResponsesForBatch(final String messageType) {
return getTopLinkTemplate().executeFind(new TopLinkCallback() {
public Object doInToplink(Session session) throws TopLinkException {
//Building expression
ExpressionBuilder builder = new ExpressionBuilder();
Expression exp = null;

// Only include Applications with the correct
// messageType in MsToTcnRequest
exp = builder.get("request").get("message_type").equal(
messageType);

// Only include Applications with to_batch=1 in
// country_response
exp = exp.and(builder.get("tobatch").equal('1'));

ReadAllQuery raq = new ReadAllQuery(CountryResponse.class, exp);
raq.addOrdering(builder.get("country").get("countrycodealpha")
.ascending());

Collection found = (Collection) session.executeQuery(raq);

Collection registered = session.getActiveUnitOfWork()
.registerAllObjects(found);
session.printIdentityMaps();
session.getActiveUnitOfWork().printRegisteredObjects();
session.getActiveUnitOfWork().validateCache();
session.getActiveUnitOfWork().validateObjectSpace();
return registered;
}
});
}

And I'm pretty sure no other part of the application has initialised the object cache, as I'm doing this locally avoiding interference from others.

I tried looking at the forums on MetaLink, but didn't find an area to get priority support on TopLink. Where can I get it?

Thanks,
Anders,
james_sutherland Apr 28 2005
When you register objects in a unit of work you should be returned complete clones of those objects. If you unit of work clones are already corrupt just by registering them, then something is going very wrong.

My only guess would be that you have a set method that has side effects in it. Are you using method access in any of your mappings, which have side effects, such as setting the inverse relationship? Methods used in the mappings are required to only set the attribute value, and should not have any side effects. You can check this by switching your mappings to use direct attribute access and see if the problem still occurs.

What can occur is that while TopLink is cloning the object in the unit of work if a 1-1 sets method sets the inverse, when TopLink builds the back clone the clone with end up with a reference to a backup causing the error that you are seeing.
426437 Apr 29 2005
You were spot on James. Thanks! The response on these forums are excellent when you americans finally wake up. ;)
Donald Smith-Oracle Apr 29 2005
We are not American, we are mostly Canadians.... :)

- Don
504035 Feb 28 2007
Donald Smith said: "these issues are soon to be obsolete"

In which version of TopLink can we except this not be an issue anymore?
1 - 8
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Mar 28 2007
Added on Apr 28 2005
8 comments
1,237 views