-
Notifications
You must be signed in to change notification settings - Fork 936
Description
Frédéric Delaporte created an issue — 19th July 2017, 0:41:01:
When updating a multi-tables entity (due to joined-subclass) with a
concat
expression, theIParameterSpecification.ExpectedType
is leftnull
which causes a null ref exception in the multi-table updater.System.NullReferenceException : La référence d'objet n'est pas définie à une instance d'un objet. à NHibernate.Param.ParametersBackTrackExtensions.<>c*_DisplayClass3_0.<GetQueryParameterTypes>b_*7(IType t) dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Param\ParametersBackTrackExtensions.cs:ligne 52 à System.Linq.Enumerable.<SelectManyIterator>d**16`2.MoveNext() à System.Linq.Buffer`1..ctor(IEnumerable`1 source) à System.Linq.Enumerable.ToArray<TSource>(IEnumerable`1 source) à NHibernate.Param.ParametersBackTrackExtensions.GetQueryParameterTypes(IEnumerable`1 parameterSpecs, IList`1 sqlQueryParametersList, ISessionFactoryImplementor factory) dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Param\ParametersBackTrackExtensions.cs:ligne 52 à NHibernate.Hql.Ast.ANTLR.Exec.MultiTableUpdateExecutor.Execute(QueryParameters parameters, ISessionImplementor session) dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Hql\Ast\ANTLR\Exec\MultiTableUpdateExecutor.cs:ligne 151 à NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.ExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session) dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Hql\Ast\ANTLR\QueryTranslatorImpl.cs:ligne 162 à NHibernate.Engine.Query.HQLQueryPlan.PerformExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session) dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Engine\Query\HQLQueryPlan.cs:ligne 183 à NHibernate.Impl.SessionImpl.ExecuteUpdate(IQueryExpression queryExpression, QueryParameters queryParameters) dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:ligne 2470 à NHibernate.Impl.AbstractQueryImpl2.ExecuteUpdate() dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate\Impl\AbstractQueryImpl2.cs:ligne 36 à NHibernate.Test.LinqBulkManipulation.Fixture.MultiTableHqlUpdate() dans E:\Projets\nhibernate\nhibernate-core\src\NHibernate.Test\LinqBulkManipulation\Fixture.cs:ligne 550
This was found by attempting a Linq update. Here are the examples, failing if put in the linq bulk update fixture from (#391).
[Test] public void MultiTableHqlUpdate() { using (var s = OpenSession()) using (s.BeginTransaction()) { s.CreateQuery("update Human h set h.Description = concat(h.Description, :p)") .SetParameter("p", " a") .ExecuteUpdate(); } } [Test] public void MultiTableUpdate() { using (var s = OpenSession()) using (s.BeginTransaction()) { var count = s .Query<Human>() .Update() .As(a => new Human { Description = a.Description + " a" }); } }
Frédéric Delaporte added a comment — 19th July 2017, 0:46:12:
The HQL case is easy to work around, just change
concat
by+
. That is harder for Linq. The trouble may be more frequent with Linq. When we have a+
, it is handled as a binary node in AST, and some custom logic attempts to set the expected type of any parameter in one side thanks to the type of the other side. When we have aconcat
, it is handled as a method, without any assumption about which type each argument could have, causing parameters inside theconcat
to stay without anExpectedType
.Then the
MultiTableUpdateExecutor
fails when callingParametersBackTrackExtensions.GetQueryParameterTypes
, which mandates every parameter to have an expected type. A comment tell to callResetEffectiveExpectedType
before callingGetQueryParameterTypes
, but I do not know all the implications, whether it is really the good fix for that case or not, ... And whether we should, instead of reseting all parameters, just "reset" the ones lacking an expected type, or not.