Description
Hello,
we have encountered a problem with NHIbernate after updating form 5.1.1 to 5.2.5.
We are using JoinAlias and projection to gain extra performance at some points in the program.
I've created a test solution which is encapsulated from our program to show you the different behaviour between the two version (Attachment NHibernate_Test.zip, containing a VS Solution):
NHibernate_test.zip
Here's the Query which is causing the issue (Also in the test solution):
public static IList<WorkstepFeatureLiteRequestBean> PerformSelect(long? featureSetTemplateId, long? featureSetId)
{
using (var session = _sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction(IsolationLevel.ReadCommitted))
{
Workstep workstepAlias = null;
Feature featureAlias = null;
FeatureSet featureSetAlias = null;
FeatureSetTemplate featureSetTemplateAlias = null;
FeatureTemplate featureTemplateAlias = null;
FeatureType featureTypeAlias = null;
var selectedTypes = BaseData.FeatureTypes.Take(2).ToList();
var query = session.QueryOver(() => workstepAlias);
if (featureSetTemplateId.HasValue)
{
query = query
.JoinAlias(x => x.FeatureSetTemplate, () => featureSetTemplateAlias)
.And(() => featureSetTemplateAlias.Id == featureSetTemplateId.Value);
}
if (featureSetId.HasValue)
{
query = query
.JoinAlias(x => x.FeatureSet, () => featureSetAlias)
.And(() => featureSetAlias.Id == featureSetId);
}
if (!featureSetId.HasValue)
{
query = query.JoinAlias(x => x.FeatureSet, () => featureSetAlias);
}
if (!featureSetTemplateId.HasValue)
{
query = query.JoinAlias(x => x.FeatureSetTemplate, () => featureSetTemplateAlias);
}
WorkstepFeatureLiteRequestBean bean = null;
var fullQuery = query
.JoinQueryOver(x => x.FeatureSet.Features, () => featureAlias)
.JoinQueryOver(x => x.FeatureTemplate, () => featureTemplateAlias)
.JoinQueryOver(x => x.FeatureType, () => featureTypeAlias)
.And(x => x.FeatureKey.IsIn(selectedTypes))
.SelectList(x => x
.Select(() => workstepAlias.Id).WithAlias(() => bean.WorkstepId)
.Select(() => workstepAlias.Uuid).WithAlias(() => bean.WorkstepUuid)
.Select(() => workstepAlias.Name).WithAlias(() => bean.WorkstepName)
.Select(() => workstepAlias.JointIndex).WithAlias(() => bean.WorkstepJointIndex)
.Select(() => featureSetTemplateAlias.Name).WithAlias(() => bean.FeatureSetTemplateName)
.Select(() => featureSetAlias.Name).WithAlias(() => bean.FeatureSetName)
.Select(() => featureAlias.Id).WithAlias(() => bean.FeatureId)
.Select(() => featureAlias.Uuid).WithAlias(() => bean.FeatureUuid)
.Select(() => featureTemplateAlias.Name).WithAlias(() => bean.FeatureName)
.Select(() => featureTypeAlias.FeatureKey).WithAlias(() => bean.FeatureType)
)
.TransformUsing(Transformers.AliasToBean<WorkstepFeatureLiteRequestBean>());
var filteredWorksteps = fullQuery.List<WorkstepFeatureLiteRequestBean>();
transaction.Commit();
return filteredWorksteps;
}
}
}
The SQL NHibernate generates looks like this in version 5.1.1 (which is fine and working):
SELECT this_.id AS y0_,
this_.uuid AS y1_,
this_.NAME AS y2_,
this_.jointindex AS y3_,
featureset2_.NAME AS y4_,
featureset1_.NAME AS y5_,
featureali3_.id AS y6_,
featureali3_.uuid AS y7_,
featuretem4_.NAME AS y8_,
featuretyp5_.featurekey AS y9_
FROM nh_ja_workstep this_
INNER JOIN nh_ja_featuresettemplate featureset2_
ON this_.featuresettemplate_id = featureset2_.id
INNER JOIN nh_ja_featureset featureset1_
ON this_.featureset_id = featureset1_.id
INNER JOIN nh_ja_feature featureali3_
ON featureset1_.id = featureali3_.featureset_id
INNER JOIN nh_ja_featuretemplate featuretem4_
ON featureali3_.featuretemplate_id = featuretem4_.id
INNER JOIN nh_ja_featuretype featuretyp5_
ON featuretem4_.featuretype_id = featuretyp5_.id
WHERE featuretyp5_.featurekey IN ( @p0, @p1 )
But in version 5.2.5 the produced statement looks like this (which is not working):
SELECT this_.id AS y0_,
this_.uuid AS y1_,
this_.NAME AS y2_,
this_.jointindex AS y3_,
featureset2_.NAME AS y4_,
featureset1_.NAME AS y5_,
featureali3_.id AS y6_,
featureali3_.uuid AS y7_,
featuretem4_.NAME AS y8_,
featuretyp5_.featurekey AS y9_
FROM nh_ja_workstep this_
INNER JOIN nh_ja_featuresettemplate featureset2_
ON this_.featuresettemplate_id = featureset2_.id
INNER JOIN nh_ja_featureset featureset1_
ON this_.featureset_id = featureset1_.id
WHERE featuretyp5_.featurekey IN ( @p0, @p1 )
Serveral joins are missing in the produced statement and cannot be executed by the database (Tested on MSSQL 14 & Oracle 12c).