Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fetch="join" mapping is ignored in hql/Linq queries #2716

Open
deAtog opened this issue Mar 29, 2021 · 4 comments
Open

fetch="join" mapping is ignored in hql/Linq queries #2716

deAtog opened this issue Mar 29, 2021 · 4 comments

Comments

@deAtog
Copy link
Contributor

deAtog commented Mar 29, 2021

Given the following mapping:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" namespace="NHibernate.Test.NHSpecificTest.GH2552">
  <class name="Person">
    <cache usage="read-write"/>
    <id name="Id" unsaved-value="0" generator="native"/>
    <property name="Name"/>
    <one-to-one name="Details" class="Details" fetch="join" cascade="all-delete-orphan"/>
  </class>

  <class name="Details">
    <cache usage="read-write"/>
    <id name="Id" unsaved-value="0">
      <generator class="foreign">
        <param name="property">Person</param>
      </generator>
    </id>
    <one-to-one name="Person" class="Person" constrained="true"/>
    <property name="Data"/>
  </class>
</hibernate-mapping>

With the following implementations:

public class Person {
    private Details _details;

    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }

    public virtual Details Details {
        get { return _details; }
        set {
            _details = value;

            if (_details != null) {
                _details.Person = this;
            }
        }
    }
}

public class Details {
    public virtual int Id { get; protected set; }
    public virtual Person Person { get; set; }
    public virtual string Data { get; set; }
}

The following methods of obtaining a Person/people yield different queries and different execution strategies. All of the results can be classified as one of the following:

  1. Generates a single query for both Person and Details using outer join. (In my opinion, this is the correct and expected behavior)
session.Get<Person>(id);

session.QueryOver<Person>()
    .Where(p => p.Id == id)
    .SingleOrDefault();

session.QueryOver<Person>()
    .List();

session.CreateCriteria<Person>()
    .Add(Restrictions.Eq("Id", id))
    .UniqueResult<Person>();

session.CreateCriteria<Person>()
    .Add(Restrictions.IdEq(id))
    .UniqueResult<Person>();

session.CreateCriteria<Person>()
    .List();
  1. Generates a single query for only the properties of Person and additional queries for the properties Details of each Person returned.
session.Query<Person>()
    .Where(p => p.Id == id)
    .SingleOrDefault();

session.Query<Person>()
    .List();

The behavior exhibited in the first set is the expected behavior as the one-to-one relationship specifies a fetch type of join. Verification of this issue relies on #2714 being fixed.

@bahusoid
Copy link
Member

bahusoid commented Mar 29, 2021

That's actually a known behavior - fetch="join" mapping is ignored for hql/LINQ queries. It's even kinda documented:

The fetch strategy defined in the mapping document affects:
...
* HQL queries if subselect fetching is used

While I'm not against to have this feature it's simply not implemented. Latest hibernate behaves the same.

Verification of this issue relies on #2714 being fixed

To check queries for lazy associations there is EntityFetchCount property - you don't really need #2714 to verify it. So it looks to me you just need to find all required properties and sum them if you need total queries - I still believe QueryExecutionCount works as intended and doesn't need fixing.

@bahusoid bahusoid changed the title Inconsistent One-to-one query generation/execution fetch="join" mapping is ignored in hql/Linq queries Mar 29, 2021
@deAtog

This comment was marked as resolved.

@bahusoid

This comment was marked as resolved.

@deAtog

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants