-
Notifications
You must be signed in to change notification settings - Fork 934
InvalidWithClauseException when join polymorphic entity #2580
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
Comments
I don't see how #2078 can lead to exception you see. Can you provide example of query that stopped working in 5.3?
This check is no longer present in master (5.4) branch. But it's part of bigger changes that won't be backported to 5.3 branch |
Sure, here a simplified example that leads to the exception. Let's say we have Mappings
QueryNow a query that will get all children ids belonging to a parent via the family:
ExceptionWe get this stack trace:
|
Ok. I see. #2078 is unrelated. And I'm afraid simple removal of exception won't really help you unless SQLite is your only database. The problem is that in 5.3 we started to use real inner/left joins in generated SQL for LINQ queries instead of implicit joins (#2327, #2328). But your case with subclasses is not handled nicely as you use base table column in ON statement. SQL generated in 5.3 with exception removed: SELECT DISTINCT childentit1_.Person_Id AS col_0_0_
FROM Adults adultentit0_
INNER JOIN Persons adultentit0_1_ ON adultentit0_.Person_Id = adultentit0_1_.Person_Id
INNER JOIN Children childentit1_ ON (childentit1_1_.Family_Id = adultentit0_1_.Family_Id) -- <-- childentit1_1_ is not yet joined
INNER JOIN Persons childentit1_1_ ON childentit1_.Person_Id = childentit1_1_.Person_Id
WHERE adultentit0_.Person_Id = @p0 As you can see in 5.3 base table As a workaround in 5.3 you can use cross join for such queries (kinda simulate behavior of 5.2): var ids = (from adult in session.Query<AdultEntity>()
from child in session.Query<ChildEntity>() //join is replaced with from and ON condition is moved to where
where adult.Family.Id == child.Family.Id && adult.Id == adultId
select child.Id)
.Distinct()
.ToList(); |
Maybe just for 5.3 we should simply fallback to cross join if inner entity join is done on polymorphic entity... Don't know LINQ parts very well but seems this logic can be placed here Can be reproduced adding the following test to [Test(Description = "GH-2580")]
public void CanInnerJoinOnSubclassWithBaseTableReferenceInOnClause()
{
var result = (from o in db.Animals
join o2 in db.Mammals on o.BodyWeight equals o2.BodyWeight
select new {o, o2}).Take(1).ToList();
} |
@maca88, may you take a look on this issue? |
I've made a PR that checks whether an inherited member from another table is used in |
Fixed by #2581 |
Situation
Updating NHibernate from 5.2.7 to 5.3.3 we ran into issues with queries operating on inheritance hierarchies. We join inherited entities and run operators such as distincts or simple selects. Analyzing the exception
with clause can only reference columns in the driving table
we soon came to find the cause being theHqlSqlWalker
and itsWithClauseVisitor
. There the names of aliases are compared and if different, an exception is thrown.Comparison with Hibernate
After some research we found this to be an issue in Hibernate as well: https://hibernate.atlassian.net/browse/HHH-11383. It was fixed here: hibernate/hibernate-orm@5ac46eb.
We use NHibernate as our ORM for large-scale projects and ensure compability with a test coverage of 20K+ tests (hence we discovered this issue quickly). For testing purposes we disabled the exception (as in Hibernate) and ran our queries, which then work smoothly.
Request
Is it possible to adapt the change from Hibernate to NHibernate and disable the check of alias names in this case and consequently not throwing the exception?
On a side note: perhaps this became a problem in the first place after NHibernate release 5.3.0 and this change #2078
The text was updated successfully, but these errors were encountered: