Skip to content

NH-3845 - Make OfType work better with polymorphic mappings #456

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

abrobston
Copy link

Addresses NH-3845. The ProcessOfType Linq visitor class now handles interfaces and base classes by checking which mapped types that could be in the result set implement the class, then filtering accordingly. If no results are possible, any remaining filters are removed from the query tree to avoid problems with invalid property names.

Because the HQL tree for OfType can now mimic the ".class IN" construct, the In method of HqlTreeBuilder was inadequate to express the tree. Allowing an array of nodes to be passed as the source solves this problem.

Addresses NH-3845.  The ProcessOfType Linq visitor class now handles interfaces and base classes by checking which mapped types that could be in the result set implement the class, then filtering accordingly.  If no results are possible, any remaining filters are removed from the query tree to avoid problems with invalid property names.

Because the HQL tree for OfType can now mimic the ".class IN" construct, the In method of HqlTreeBuilder was inadequate to express the tree.  Allowing an array of nodes to be passed as the source solves this problem.
@hazzik
Copy link
Member

hazzik commented Feb 14, 2016

I believe that you need to use ExpressionList instead of modifying In

@abrobston
Copy link
Author

I tried using ExpressionList, and it causes an exception at parse time. When using the HQL construct where EntityName.class in (Some.Class, Some.Other.Class), the parse tree places the two class names (as Ident nodes) as direct children of the InList node, which in turn is the child of the In node. The changes in this commit replicate that behavior.

{
public virtual int MainEntityId { get; set; }
public virtual string Text { get; set; }
public virtual ISet<IPropertyEntityBase> Properties { get; protected set; } = new HashSet<IPropertyEntityBase>();
Copy link
Member

Choose a reason for hiding this comment

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

C# 6 is not yet supported by our build engine, please change to using C#5

@hazzik
Copy link
Member

hazzik commented Feb 15, 2016

Ok, understand.
Please remove usage of C#6 language features

@abrobston
Copy link
Author

I found another facet of the same bug, and I'm likely to be amending the pull request once I can create a minimal test case for it.

Continues to address NH-3845.  Because OfType is one of the result operators removed from its subquery and attached to the main query, it is not always clear during the ProcessOfType.Process method which query source should be used to retrieve the .class property of the entity.  Sometimes the query type is in the QueryModel.MainFromClause, and sometimes it is in the QueryModel.SelectClause.  It may be elsewhere, also.  For queries in which OfType will match some but not necessarily all results, attempt to determine and use the query name as an identifier rather than using the source expression, for example.  Doing so simplifies this particular Process method while still allowing query source determination later.
@hazzik
Copy link
Member

hazzik commented Feb 19, 2016

You will also need to check the caching issues. Please check that query do process correctly with regardless the type you specify.

@abrobston
Copy link
Author

@hazzik, I'm not entirely sure what you mean when referring to "check the caching issues." Do you have a test case or example of some kind? Or, can you tell me where to look for a similar unit test?

@hazzik
Copy link
Member

hazzik commented Feb 19, 2016

Start exploring from NH-2500 in JIRA. I can provide more resources later

Two additional test methods check whether the changes for NH-3845 cause problems with query parameters being cached.
@abrobston
Copy link
Author

I added two unit test methods to check for cache issues similar to those NH-2500 describes. The tests pass. If there are other scenarios I should check, please let me know.

@abrobston
Copy link
Author

I'm having some issues with another test case that I found does not pass. I posted to the nhibernate-developers Google Group, so see discussion there once my post is released from moderation.

@abrobston
Copy link
Author

The Google Group thread has one reply, but more information would be very helpful.

@hazzik
Copy link
Member

hazzik commented Feb 14, 2017

Related to #553. The #553 contains more clear logic, which, I think shall be ported here.

@hazzik
Copy link
Member

hazzik commented Feb 14, 2017

Happy birthday, PR!

@hazzik hazzik changed the title Make OfType work better with polymorphic mappings NH-3845 - Make OfType work better with polymorphic mappings Feb 14, 2017
@hazzik hazzik removed the Need JIRA label Feb 14, 2017
@@ -416,7 +416,7 @@ public HqlFalse False()
return new HqlFalse(_factory);
}

public HqlIn In(HqlExpression itemExpression, HqlTreeNode source)
public HqlIn In(HqlExpression itemExpression, params HqlTreeNode[] source)
Copy link
Member

Choose a reason for hiding this comment

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

I've found the proper solution for not changing this. You need to use HqlTreeBuilder.ExpressionSubTreeHolder.

if (persister != null)
{
fromItemTypePersisters.Add(persister);
persister.EntityMetamodel.SubclassEntityNames.ToList().ForEach(fromItemImplementorQueue.Enqueue);
Copy link
Member

@hazzik hazzik Feb 14, 2017

Choose a reason for hiding this comment

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

Please do not use .ForEach. Use the proper loop instead.

@hazzik
Copy link
Member

hazzik commented Feb 14, 2017

I've extracted the issue with unmapped base classes and interfaces to a new feature request NH-3947.

@hazzik
Copy link
Member

hazzik commented Jun 24, 2017

Can you please enable Allow edits from maintainers option on this PR?

Copy link
Member

@hazzik hazzik left a comment

Choose a reason for hiding this comment

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

Please rebase on top of master. Also, the solution needs to be incorporated into is/as case.

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

Successfully merging this pull request may close these issues.

2 participants