Refreshing objects with @Transient fields [message #387103] |
Thu, 16 April 2009 13:22 |
Mark Howard Messages: 10 Registered: July 2009 |
Junior Member |
|
|
Hi,
I have a number of @Transient fields, which are populated from an
@PostLoad method, based on a char[] clob (eagerly fetched).
This fails in one specific case:
When an entity is loaded in a transaction, say with a null clob, then
entityManager.refresh()'d, the clob is updated (now not null, due to
changes in the database), but the transient fields are not updated.
With a little debugging, I found that the PostLoad method *is* called and
the transient field is set, but this is all on a different instance of the
entity.
It seems that eclipselink is performing the refresh operation on a clone
of the entity, then copying the non-transient fields back to the object.
Is this a bug?
Is there any workaround to try?
Further calls to find the entity from the same transaction have the same
effect (new version of the clob, old version of the transient field). A
call from a separate transaction returns the new version of the clob and
transient field.
I've tried this with both 1.0.2 and 1.1.0 and get the same effect.
If it helps, here's the stack trace from when the @PostLoad method is
called. this is invoked on a different entity to the one I'm refreshing.
at sun.reflect.GeneratedMethodAccessor73.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe thodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.eclipse.persistence.internal.security.PrivilegedAccessHe lper.invokeMethod(PrivilegedAccessHelper.java:344)
at
org.eclipse.persistence.internal.jpa.metadata.listeners.Enti tyListener.invokeMethod(EntityListener.java:297)
at
org.eclipse.persistence.internal.jpa.metadata.listeners.Enti tyClassListener.invokeMethod(EntityClassListener.java:64)
at
org.eclipse.persistence.internal.jpa.metadata.listeners.Enti tyListener.postRefresh(EntityListener.java:398)
at
org.eclipse.persistence.descriptors.DescriptorEventManager.n otifyListener(DescriptorEventManager.java:638)
at
org.eclipse.persistence.descriptors.DescriptorEventManager.n otifyEJB30Listeners(DescriptorEventManager.java:593)
at
org.eclipse.persistence.descriptors.DescriptorEventManager.e xecuteEvent(DescriptorEventManager.java:187)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildAttributesIntoObject(ObjectBuilder.java:322)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObject(ObjectBuilder.java:677)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildWorkingCopyCloneNormally(ObjectBuilder.java:547)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObjectInUnitOfWork(ObjectBuilder.java:517)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObject(ObjectBuilder.java:461)
at
org.eclipse.persistence.internal.descriptors.ObjectBuilder.b uildObject(ObjectBuilder.java:413)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.buildOb ject(ObjectLevelReadQuery.java:521)
at
org.eclipse.persistence.queries.ReadObjectQuery.registerResu ltInUnitOfWork(ReadObjectQuery.java:707)
at
org.eclipse.persistence.queries.ReadObjectQuery.executeObjec tLevelReadQuery(ReadObjectQuery.java:431)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.execute DatabaseQuery(ObjectLevelReadQuery.java:879)
at
org.eclipse.persistence.queries.DatabaseQuery.execute(Databa seQuery.java:666)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.execute (ObjectLevelReadQuery.java:840)
at
org.eclipse.persistence.queries.ReadObjectQuery.execute(Read ObjectQuery.java:398)
at
org.eclipse.persistence.queries.ObjectLevelReadQuery.execute InUnitOfWork(ObjectLevelReadQuery.java:902)
at
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.int ernalExecuteQuery(UnitOfWorkImpl.java:2587)
at
org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1178)
at
org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1162)
at
org.eclipse.persistence.internal.sessions.AbstractSession.ex ecuteQuery(AbstractSession.java:1108)
at
org.eclipse.persistence.internal.jpa.EntityManagerImpl.refre sh(EntityManagerImpl.java:423)
at
org.apache.openejb.persistence.JtaEntityManager.refresh(JtaE ntityManager.java:158)
Many thanks in advance for any help or ideas you give.
Regards,
Mark Howard
|
|
|
Re: Refreshing objects with @Transient fields [message #387367 is a reply to message #387103] |
Mon, 20 April 2009 13:58 |
|
Looking at the code, this appears to a bug. The PostLoad event should be
called on the clone. The issues is that PostLoad is translated into the
EclipseLink Descriptor events, PostRefresh and PostClone, however
PostRefresh is not called on the clone in a refresh in a UnitOfWork when
outside of an early transaction (but it should be). It is also odd that
PostBuild does not also trigger a PostLoad, as this would be required for
read-only objects.
Please log a bug for this.
As a workaround if you register for the Descriptor event PostMerge, you
should get this event in your refresh. You can register for the event
using a DescriptorCustomizer to configure the DescriptorEventManager of
the ClassDescriptor.
---
James
http://www.nabble.com/EclipseLink---Users-f26658.html
James : Wiki : Book : Blog : Twitter
|
|
|
|
Powered by
FUDForum. Page generated in 0.02823 seconds