We're creating a RCP application and we use EMF resources to load our data. We're in need of calling an Oracle stored procedure to modify our data. After the procedure we want to refresh one single object, but that causes some problems.

This is our simplified model:

- Folder
-- documents : Document (opposite: folder)

- Document
-- folder : Folder (opposite: documents)

Our procedure deletes a document from the database so we want to refresh our folder. I expected the documents reference to update automatically, but instead it tries to load the deleted object. This is the error we get:

org.hibernate.UnresolvableObjectException: No row with the given identifier exists: [Document#1161401]
at org.hibernate.UnresolvableObjectException.throwIfNull(UnresolvableObjectException.java:64)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:159)
at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1044)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1029)
at org.hibernate.engine.spi.CascadingAction$3.cascade(CascadingAction.java:205)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:123)
at org.hibernate.event.internal.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:64)
at org.hibernate.internal.SessionImpl.fireRefresh(SessionImpl.java:1036)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1013)
at org.hibernate.internal.SessionImpl.refresh(SessionImpl.java:1008)

This is the code we execute after the procedure:

session.refresh(folder);

On this forum I read the not-found="ignore" prevents the error from happening but I can't set this because I use the EOpposite...

I finally found how to achieve the not-found="ignore" functionality, doing:

@NotFound(action=NotFoundAction.IGNORE)

But this solves part of the problem.. now it complains for every reference inside the document.. So it ignores the document, but it tries to refresh the references of it. That doesn't make sense.. Should the ignore be set on every reference?

Hi Ricky,
This cascade setting means that the merge and refresh actions are not cascaded to the referenced objects. Depending on
what the stored procedure changes this may or may not be a good idea...

Btw, you can also iterate/walk over the object graph yourselve to do refresh explicitly if you want it to be cascaded.

gr. Martin

On 05/07/2013 04:36 PM, Ricky de Klerck wrote:
> Replying on my own post again..
>
> When setting PersistenceOptions.CASCADE_POLICY_ON_NON_CONTAINMENT to 'PERSIST' instead of 'MERGE, PERSIST, REFRESH' it
> works.
> Now I only have to find out what effect this has on my application..

Hi Ricky,
The best approach is to remove refresh from the cascade option (so set the CASCADE_POLICY_ON_NON_CONTAINMENT to only
PERSIST and MERGE).

Then refresh the objects you want to refresh explicitly, so if you refresh a parent then if also the children need to be
refreshed to do that explicitly for each one of them.

Or could it be that the object itself is already deleted? In that case I would catch the exception and remove the object
from the resource explicitly also.

gr. Martin

On 05/08/2013 09:39 AM, Ricky de Klerck wrote:
> Ok, but when I do need the refresh/merge I have to set the @NotFound in every reference below my Document? Otherwise it
> produces an error when refreshing after a Document is deleted