How to update object with lazy properties (proxy object) in another session?

1.2k views Asked by At

I attempted to get the object that has lazy properties in a session and tried to update it in another session. But it failed to do so with an Error: No persister for SecUserProxy (actual class is SecUser)

I'm using NHibernate 3.4. When I googled I came to know its a bug which has been fixed.

I also came across this post in which it is said if your proxy object implements INhibernateProxy, you can unproxy the object with NHibernate. As NHibernate no longer supports pluggable proxy factories (like Castle, LinFu etc), it uses an internal one, I'm assuming the internal one is perhaps INhibernateProxy

So I did the following in New session where I want to update my object as:

 object unprox_obj = Session
     .GetSessionImplementation()
     .PersistenceContext.Unproxy(secUserobj);

in anticipation of getting this same object but with the real type i-e SecUser so that it can update without any error. But it still returns a proxy object.

I'm not able to understand what is going on?

Updated: I have realized just now that 'secUserobj' is not INhibernateProxy. So How can I make it INhibernateProxy in order to update my object within another session?

 if (secUserobj is INHibernateProxy)
 {
     unprox_obj = Session
        .GetSessionImplementation()
        .PersistenceContext.Unproxy(secUserobj);
 }
1

There are 1 answers

2
Radim Köhler On BEST ANSWER

Detached objects (loaded in one session, and kept as reference) could be re-attached. We can use session.Merge() or session.Lock()

9.4.2. Updating detached objects

Many applications need to retrieve an object in one transaction, send it to the UI layer for manipulation, then save the changes in a new transaction....

...

...The last case can be avoided by using Merge(Object o). This method copies the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. The method returns the persistent instance. If the given instance is unsaved or does not exist in the database, NHibernate will save it and return it as a newly persistent instance. Otherwise, the given instance does not become associated with the session. In most applications with detached objects, you need both methods, SaveOrUpdate() and Merge().

19.1.4. Initializing collections and proxies

...
You may also attach a previously loaded object to a new ISession with Merge() or Lock() before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly should not do this automatically, since it would introduce ad hoc transaction semantics!
...

So, we can pass detached reference into .Merge(), and later work with returned (brand new) object reference:

MyEntity reAttached = session.Merge<MyEntity>(detached);

Be careful, this should be done (as stated above) before any of the detached collections were touched.