How to get a reference to proxy if I have reference to ...

16 views
Skip to first unread message

epitka

unread,
Nov 22, 2008, 11:13:57 AM11/22/08
to nhusers
... proxied class. I am running in situation that I need to get
reference to instance of a proxy when I have reference to a proxied
object. I am adding a LoadCollection listener, and collection.Owner is
a proxied class and instance of owner is proxy, so when I do
bidirectional relationship synchronization this might fail

Assert.IsTrue(ReferenceEquals(invoice, invoice.lineItems[1].invoice)

because the "invoice" is a proxy and invoice.lineItems[1].invoice is
the instance of the collection.Owner. Since I have real class I wonder
if I could look up somehow what is the proxy instance for it.

Ken Egozi

unread,
Nov 22, 2008, 11:21:09 AM11/22/08
to nhu...@googlegroups.com
I'd think that ReferenceEquels is not appropriate here.
'equality' in terms of persisted objects, is either through the PK (for entities) or the combination of all properties (for Value Objects).
It's perfectly allright imo for a DAL of any kind to represent the exact same DB row in two actual in-memory objects.

Fabio Maulo

unread,
Nov 22, 2008, 11:26:13 AM11/22/08
to nhu...@googlegroups.com
INHibernateProxy p = owner as INHibernateProxy
Then take a look ILazyInitializer

2008/11/22 epitka <exptra...@yahoo.com>



--
Fabio Maulo

epitka

unread,
Nov 22, 2008, 11:30:49 AM11/22/08
to nhusers
I am creating auto-synchronizing collection, and for that I need
references to the same instance. If I do for example:

invoice.lineItems.Add(item);
item.invoice = invoice;

I would not have this issue, but since I "must" have auto-synch
collection, I need to get the reference to the proxy. Unfortunatelly,
in this code
collection.Owner is not a proxy, but original proxied object. I can
get around that if collection fetched has at least one member, because
I can look up inverse property in the item, but if there are no items
in the collection, I get above mentioned problem.

public void OnInitializeCollection(InitializeCollectionEvent @event)
{

IPersistentCollection collection = @event.Collection;
ISessionImplementor source = @event.Session;
CollectionEntry ce =
source.PersistenceContext.GetCollectionEntry(collection);
bool wasInitialized = collection.WasInitialized;

defaultListener.OnInitializeCollection(@event);

if (!wasInitialized)
{
string role = ce.LoadedPersister.Role;
string propertyName = role.Substring(role.LastIndexOf
(".") + 1);
PropertyInfo pi = collection.Owner.GetType
().GetProperty(propertyName);

epitka

unread,
Nov 22, 2008, 11:45:24 AM11/22/08
to nhusers
Awesome, I'll try that.

On Nov 22, 10:26 am, "Fabio Maulo" <fabioma...@gmail.com> wrote:
> INHibernateProxy p = owner as INHibernateProxy
> Then take a look ILazyInitializer
>
> 2008/11/22 epitka <exptrade2...@yahoo.com>

Fabio Maulo

unread,
Nov 22, 2008, 11:52:39 AM11/22/08
to nhu...@googlegroups.com
BTW I would like to understand the requirement for the needing to go so deep in NH.

2008/11/22 epitka <exptra...@yahoo.com>



--
Fabio Maulo

Fabio Maulo

unread,
Nov 22, 2008, 11:57:59 AM11/22/08
to nhu...@googlegroups.com
2008/11/22 Ken Egozi <ego...@gmail.com>

I'd think that ReferenceEquels is not appropriate here.
'equality' in terms of persisted objects, is either through the PK (for entities) or the combination of all properties (for Value Objects).
It's perfectly allright imo for a DAL of any kind to represent the exact same DB row in two actual in-memory objects.

POID only where available, or "natural id" where the POID is not available is acceptable too ;)
--
Fabio Maulo

epitka

unread,
Nov 22, 2008, 12:13:05 PM11/22/08
to nhusers
Well, I am leading a project of generating complete MVC type web
application with POCO domain layer and NH and ORM from domain
developed using Intelliun's VE Enterprise (www.intelliun.com). One of
the features of this platform is auto synchronizing of bidirectional
relationships.
Anyway, I looked at the Abstract, Basic and Casle initializer, yet I
don't see a way to get proxy from proxied class, only to get
underlying persistent object from the proxy. Am I missing something?


On Nov 22, 10:57 am, "Fabio Maulo" <fabioma...@gmail.com> wrote:
> 2008/11/22 Ken Egozi <egoz...@gmail.com>

epitka

unread,
Nov 22, 2008, 12:26:27 PM11/22/08
to nhusers
Also, my previous question about batched lazy loads has the same
reason; namely platform allows for lazy loading in batches, that one
can specify in a resource file.

On Nov 22, 10:52 am, "Fabio Maulo" <fabioma...@gmail.com> wrote:
> BTW I would like to understand the requirement for the needing to go so deep
> in NH.
>
> 2008/11/22 epitka <exptrade2...@yahoo.com>

Fabio Maulo

unread,
Nov 22, 2008, 12:41:42 PM11/22/08
to nhu...@googlegroups.com
I don't understand what you are looking for.
You have an object instance named "pepe".
To know if pepe is a proxy:  pepe as INHibernateProxy  and etc. etc.
If pepe is a proxy you have the ILazyInitializer to know various things including the underlining instance the proxy are proxying.
/// <summary>
/// Return the Underlying Persistent Object, initializing if necessary.
/// </summary>
/// <returns>The Persistent Object this proxy is Proxying.</returns>
object GetImplementation();

/// <summary>
/// Return the Underlying Persistent Object in a given <see cref="ISession"/>, or null.
/// </summary>
/// <param name="s">The Session to get the object from.</param>
/// <returns>The Persistent Object this proxy is Proxying, or <see langword="null" />.</returns>
object GetImplementation(ISessionImplementor s);


2008/11/22 epitka <exptra...@yahoo.com>



--
Fabio Maulo

epitka

unread,
Nov 22, 2008, 1:51:53 PM11/22/08
to nhusers
I have a "pepe' and I know it is not a proxy, but there is a proxy
created for "pepe", and I need that proxy that was created for pepe.
In the DafaultCollectionInitializeEventListener, I have a non-proxy
through collection.owner, now I need to get the proxy that was already
created for this object.



On Nov 22, 11:41 am, "Fabio Maulo" <fabioma...@gmail.com> wrote:
> I don't understand what you are looking for.You have an object instance
> named "pepe".
> To know if pepe is a proxy:  pepe as INHibernateProxy  and etc. etc.
> If pepe is a proxy you have the ILazyInitializer to know various things
> including the underlining instance the proxy are proxying.
> /// <summary>
> /// Return the Underlying Persistent Object, initializing if necessary.
> /// </summary>
> /// <returns>The Persistent Object this proxy is Proxying.</returns>
> object GetImplementation();
>
> /// <summary>
> /// Return the Underlying Persistent Object in a given <see
> cref="ISession"/>, or null.
> /// </summary>
> /// <param name="s">The Session to get the object from.</param>
> /// <returns>The Persistent Object this proxy is Proxying, or <see
> langword="null" />.</returns>
> object GetImplementation(ISessionImplementor s);
>
> 2008/11/22 epitka <exptrade2...@yahoo.com>

Richard (Google)

unread,
Nov 25, 2008, 5:43:41 AM11/25/08
to nhusers
Hi epitka,

If you re-load the object from the session, you'll get the proxy back (and
it won't hit the database). In the past I've added a 'This' property on my
domain class to do this:

private Pepe This
{
get
{
return Session.Load<Pepe>(typeof(Pepe), Id);
}
}

http://forum.hibernate.org/viewtopic.php?t=982610&highlight=

Is that what you are after?

Cheers,
Richard

--------------------------------------------------
From: "epitka" <exptra...@yahoo.com>
Sent: Saturday, November 22, 2008 6:51 PM
To: "nhusers" <nhu...@googlegroups.com>
Subject: [nhusers] Re: How to get a reference to proxy if I have reference
to ...

epitka

unread,
Nov 26, 2008, 9:13:18 AM11/26/08
to nhusers
Thank you, thank you. Now i can intercept lazy initialization and set
additional operations, flags etc on my implementation of the
PersistentBag. Every relationship in my classes is annotated with a
RelationshipAttribute that I use to do auto-synchronization of the bi-
directional relationships.

[Relationship("lineItems", RelationshipType.Aggregation,
Cardinality.OneOrMore, inverseProperty = "invoice")]
public virtual IBag<LineItem> lineItems
{

//Set up relationship synchronization on the bag after collection has
been initialized.
namespace MC.NHibernate.Collections
{
public class InitializeCollectionEventListener :
IInitializeCollectionEventListener
{
#region Implementation of IInitializeCollectionEventListener

private readonly DefaultInitializeCollectionEventListener
defaultListener;

public InitializeCollectionEventListener()
{
defaultListener = new
DefaultInitializeCollectionEventListener();
}


public void OnInitializeCollection(InitializeCollectionEvent
@event)
{
IPersistentCollection collection = @event.Collection;
ISessionImplementor source = @event.Session;
CollectionEntry ce =
source.PersistenceContext.GetCollectionEntry(collection);
bool wasInitialized = collection.WasInitialized;

defaultListener.OnInitializeCollection(@event);

if (!wasInitialized)
{
string role = ce.LoadedPersister.Role;
string propertyName = role.Substring(role.LastIndexOf
(".") + 1);
Type ownerType = collection.Owner.GetType();
PropertyInfo pi = ownerType.GetProperty(propertyName);

object[] attributes = pi.GetCustomAttributes(typeof
(RelationshipAttribute), true);
if (attributes.Length == 1)
{
RelationshipAttribute ra = (RelationshipAttribute)
attributes[0];
if (String.IsNullOrEmpty(ra.inverseProperty) ==
false)
{
MethodInfo mi = pi.PropertyType.GetMethod
("SetUpRelationshipSynch");

//get a proxy class so that references
object owner = @event.Session.Load
(collection.Owner.GetType(), ((PersistentObject)
collection.Owner).RecordId);
mi.Invoke(collection, new[] { owner,
ra.relationshipName, ra.inverseProperty });
}
}
}
}
#endregion

On Nov 25, 4:43 am, "Richard \(Google\)" <fluke...@googlemail.com>
wrote:
> Hi epitka,
>
> If you re-load the object from the session, you'll get the proxy back (and
> it won't hit the database).  In the past I've added a 'This' property on my
> domain class to do this:
>
> private Pepe This
> {
>     get
>     {
>         return Session.Load<Pepe>(typeof(Pepe), Id);
>     }
>
> }
>
> http://forum.hibernate.org/viewtopic.php?t=982610&highlight=
>
> Is that what you are after?
>
> Cheers,
>     Richard
>
> --------------------------------------------------
> From: "epitka" <exptrade2...@yahoo.com>
Reply all
Reply to author
Forward
0 new messages