Skip to content

Improve one-to-one handling in queries #2084

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

Merged
merged 4 commits into from
Mar 27, 2019
Merged

Conversation

bahusoid
Copy link
Member

@bahusoid bahusoid commented Mar 23, 2019

Added proper column span calculation (mapping related checks extracted to GetOwnerColumnSpan);
Adjusted OneToOneType to be properly handled as parameter and projection in queries;

  1. Allows using one-to-one association in entity comparisons (fixes NH-3778 - Crash when performing a Linq query on a one-to-one mapped reference #1368)
  2. Fixes one-to-one handling for composite keys (fixes NH-3469 - Impossible to load one-to-one association with LINQ for composite-id #1309)
  3. Fixes one-to-one projections (fixes One-to-one properties not appearing in Select() projection result set #2064, fixes NH-3178 - Exception when using one-to-one properties in a criteria projections #1125)

hazzik
hazzik previously approved these changes Mar 26, 2019
@hazzik
Copy link
Member

hazzik commented Mar 26, 2019

Does it actually make sense to return 0 in GetColumnSpan for OneToOne type?

@hazzik hazzik self-requested a review March 26, 2019 10:43
@hazzik
Copy link
Member

hazzik commented Mar 26, 2019

What about criteria? Do the same queries work there?

@bahusoid
Copy link
Member Author

bahusoid commented Mar 26, 2019

Does it actually make sense to return 0 in GetColumnSpan for OneToOne type?

Yeah otherwise owner entity thinks that one-to-one entity requires N columns in owner table. And it breaks some other checks in multiple places.

@bahusoid

This comment has been minimized.

@hazzik
Copy link
Member

hazzik commented Mar 26, 2019

Yeah otherwise owner entity thinks that one-to-one entity requires N columns in owner table. And it breaks some other checks in multiple places.

Can we instead find places where it expects 0? I don't really like inconsistency between GetColumnSpan, SqlTypes and NullSafeGet. It is breaking the contract.

@bahusoid

This comment has been minimized.

@@ -44,7 +44,8 @@ public override void NullSafeSet(DbCommand st, object value, int index, bool[] s

public override void NullSafeSet(DbCommand cmd, object value, int index, ISessionImplementor session)
{
//nothing to do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to make same change to the another overload of NullSafeSet?

Copy link
Member Author

@bahusoid bahusoid Mar 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Other method is about preparing command for owner table. At least from what I've seen in tests.

@hazzik
Copy link
Member

hazzik commented Mar 26, 2019

How will this work with your other PR #2081?

@bahusoid
Copy link
Member Author

bahusoid commented Mar 26, 2019

How will this work with your other PR #2081?

It's unrelated. #2081 is about forcing join for association. Join for association is not affected by this PR. This pr fixes various explicit comparisons with one-to-one association (via parameter, null, other join...)

…rameterColumnSpan

Implement one-to-one handling without owner (to make it work in projections)
@@ -92,6 +96,16 @@ public override ForeignKeyDirection ForeignKeyDirection

public override object Hydrate(DbDataReader rs, string[] names, ISessionImplementor session, object owner)
{
if (owner == null && names.Length > 0)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also fixes #2064. But #2082 still can be applied as it optimizes processing a bit by avoiding loaded entities "rehydrating".

@@ -7,10 +7,10 @@ namespace NHibernate.Type
{
internal static class TypeExtensions
{
public static int GetParameterColumnSpan(this IType type, IMapping sessionFactory)
public static int GetOwnerColumnSpan(this IType type, IMapping sessionFactory)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it makes sense to add it to IType interface.

@bahusoid
Copy link
Member Author

Can we instead find places where it expects 0

Done. Introduced GetOwnerColumnSpan for such places.

What about criteria? Do the same queries work there?

Yes. It works with latest commit. Tests added.

@@ -324,7 +324,7 @@ public bool IsSimpleValue

public virtual bool IsValid(IMapping mapping)
{
return ColumnSpan == Type.GetColumnSpan(mapping);
return ColumnSpan == Type.GetOwnerColumnSpan(mapping);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break something called "SpecialOneToOneType".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which seems to be unsupported anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. For the code below ColumnSpan is always 0. So it's never used.

if (ColumnSpan > 0)
{
return
new SpecialOneToOneType(ReferencedEntityName, foreignKeyType, referencedPropertyName, IsLazy, UnwrapProxy,
entityName, propertyName);
}
else
{
return
TypeFactory.OneToOne(ReferencedEntityName, foreignKeyType, referencedPropertyName, IsLazy, UnwrapProxy,
entityName, propertyName);
}
}

Though I restored original behavior just in case...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should override logic for onetone.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added GetOwnerColumnSpan override to SpecialOneToOne in my latest commit. Or did you mean something else?

Copy link
Member

@hazzik hazzik Mar 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to implement override for IsValid in OneToOne to handle this logic. But it's ok.

@hazzik hazzik merged commit 95d38c1 into nhibernate:master Mar 27, 2019
@hazzik hazzik added this to the 5.3 milestone Mar 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment