Bidirectional one-to-one relation through FK (using property-ref) proxiable

Description

Hi,
In our project we use one-to-one relations that are not referencing same primary key, instead property-ref is used to specify the referenced property. In this case however we have noticed that lazy="proxy" doesn't work as expected - the "lazy" objects are eagerly loaded on loading of the parent objec

Environment

None

Activity

Show:
Fabio Maulo
May 13, 2011, 9:10 AM

The current behavior is expected due to the relation to a property that is not the PK.
NH have to hit the DB to know the value of the property holding the relation, hitting it he can initialize the object.
In practice the one-to-one through FK is not a real one-to-one and it can be transformed to a one-to-many easily. The real one-to-one is through PK.

Boyan Trushev
May 15, 2011, 11:21 PM

Hi Fabio,
Thanks for the quick reply!

>NH have to hit the DB to know the value of the property holding the relation, hitting it he can initialize the object.

Why should NH hit the DB to know the value of the property? Couldn't this be done on accessing of the "lazy" property? The object containing the property is a proxy and it could check that the property is still not initialized and then hit the DB. That's exactly what I achieved with the patch I proposed in my previous comment. Have you had a look at it?

>In practice the one-to-one through FK is not a real one-to-one and it can be transformed to a one-to-many easily. The real one-to-one is through PK.

In our current project we use POCOs and for one-to-one relation there is a single property to hold the relation, it cannot be easily transformed to one-to-many as for one-to-many we will need a list rather than just a property - which is unacceptable in our case.

Fabio Maulo
May 18, 2011, 7:29 AM

In the proxy you have the ID of the PK of the other object, not the value representing the relation (the property-ref has that value).

Boyan Trushev
May 18, 2011, 11:39 PM

I think we are in some sort of misunderstanding here...
So let me try to explain my idea with the example I gave in the test case from my first attachment. Let's have a Person entity which has one-to-one relation to an Employee:

<class name="Person">
<id name="Id" type="int">
<generator class="identity" />
</id>
<property name="Name"/>
<one-to-one name="Employee" lazy="proxy" property-ref="Person" fetch="select" />
</class>

public class Person
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Employee Employee { get; set; }
}

When a person object is loaded from the database the following query is created:

SELECT
person0_.Id as Id0_0_,
person0_.Name as Name0_0_
FROM
Person person0_
WHERE
person0_.Id=@p0;

The Employee property should not be initialized on that stage. Now if the Employee property is accessed, the person proxy finds that the property is not initialized and produces a query like that to initialize it:

SELECT
employee0_.Id as Id1_0_,
employee0_.PersonName as PersonName1_0_,
employee0_.Person as Person1_0_
FROM
Employee employee0_
WHERE
employee0_.Person=@p0;

@p0 is the person id.

With the current NH version both queries are executed on loading of the person object - the Employee property is eagerly loaded. With the patch I proposed it works exactly as I described and IMHO this is the correct behavior. Hope it is now clear what I'm trying to explain and why I have opened the ticket.

Frédéric Delaporte
June 2, 2018, 7:41 AM

Moved here.

What you are asking for should be done by setting lazy="no-proxy". lazy="proxy" mandates the association to be proxified, which mandates to knwo its primary key as explained by Fabio. lazy="no-proxy" enables the association to be lazily loaded by the owning entity (as you are asking for), owning entity which is then proxified as a lazy-property proxy.

Won't Do

Assignee

Unassigned

Reporter

Boyan Trushev

Components

Affects versions

Priority

Minor
Configure