Object Reference LINQ Com NHibernate

Passei por um problema muito simples, porém me atrasou pelo menos 1 dia de trabalho até descobrir o real problema.
O erro que estava ocorrendo era referente a uma query LINQ criada para ser executada pelo NHibernate(Versão 3.3.1), porém estava ocorrendo Object Reference no metodo TransformTuple, o stack Trace estava assim:

NHibernate.Exceptions.GenericADOException : Could not execute query[SQL: SQL not available]
  ----> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
  ----> System.NullReferenceException : Object reference not set to an instance of an object.
   at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
   at NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters)
   at NHibernate.Impl.ExpressionQueryImpl.List()
   at NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
   at Remotion.Linq.QueryableBase`1.GetEnumerator()
   at System.Linq.Enumerable.<TakeIterator>d__3a`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList(IEnumerable`1 source)
   at XXXXInfrastructure.Repository.Nhibernate.Repositorio.Repositorio.Pesquisar(Periodo periodo, Nullable`1 status, Paginacao paginacao, ref Int32 total) in EntidadeRepositorio.cs: line 59
   at Castle.Proxies.Invocations.IEntidadeRepositorio_Pesquisar.InvokeMethodOnTarget()
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at XXXX.Infrastructure.IOC.InterceptadorUnidadeTrabalho.Intercept(IInvocation invocation) in InterceptadorUnidadeTrabalho.cs: line 72
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IEntidadeRepositorioProxy.Pesquisar(Periodo periodo, Nullable`1 status, Paginacao paginacao, ref Int32 total)
   at XXXXX.Domain.Service.Interfaces.EntidadeServico.Pesquisar(EntradaPesquisarRequestVM entrada, ref Int32 total) in EntidadeServico.cs: line 52
   at Castle.Proxies.Invocations.IEntidadeServico_Pesquisar.InvokeMethodOnTarget()
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at XXXX.Infrastructure.IOC.InterceptadorUnidadeTrabalho.Intercept(IInvocation invocation) in InterceptadorUnidadeTrabalho.cs: line 72
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.IEntidadeServicoProxy.Pesquisar(EntradaEntidadePesquisarRequestVM entrada, ref Int32 total)
   at XXXX.Application.Web.Api.Controllers.EntidadeController.Pesquisar(EntidadePesquisarRequestVM requetVm) in EntidadeController.cs: line 34
   at Tests.Integrated.Application.Web.Api.EntidadeTestes.Entidade_PesquisarPorStatus_DeveEfetuarPesquisaComSucesso() in EntidadeTestes.cs: line 75
--TargetInvocationException
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at NHibernate.Linq.ResultTransformer.TransformTuple(Object[] tuple, String[] aliases)
   at NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.GetResultList(IList results, IResultTransformer resultTransformer)
   at NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters)
   at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters)
   at NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
   at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results)
--NullReferenceException
   at lambda_method(Closure, Object[])

Depois de diversas pesquisas e sem encontrar uma solução na internet ou alguem que tivesse o mesmo erro que eu, tentei outras formas de resolver o problema como trocar para criteria a query, definir um result transform customizado para entender o problemas, interceptar a query para ver se ela estava sendo gerada com problema, porém sem sucesso.

O objeto que eu teria que retornar era assim:

   public class EntidadeDTO
    {
        public int Id { get; set; }
        public DateTime DataAbertura { get; set; }
        public DateTime? DataFechamento { get; set; }
        public StatusEntidade Status { get; set; }
        public int Totalizador1 { get; set; } //SubQuery
        public int Totalizador2 { get; set; } //SubQuery
        public int Totalizador3 { get; set; } //SubQuery
        public int Totalizador4 { get; set; }        //SubQuery
        public decimal ValorAproximado { get; set; }
        public decimal ValorFinal { get; set; } //SubQuery
    }

O erro ocorria pois a subquery que calcula o ValorFinal estava retornando null ao invez de 0, por isso ocorreu esse problema alterando para decimal? o erro parou de ocorrer, então uma lição aprendida sobre LINQ junto com NHibernate é, quando executar SubQueries tente sempre utilizar Nullable. O Objeto de retorno no final ficou assim.

   public class EntidadeDTO
    {
        public int Id { get; set; }
        public DateTime DataAbertura { get; set; }
        public DateTime? DataFechamento { get; set; }
        public StatusEntidade Status { get; set; }
        public int? Totalizador1 { get; set; } //SubQuery
        public int? Totalizador2 { get; set; } //SubQuery
        public int? Totalizador3 { get; set; } //SubQuery
        public int? Totalizador4 { get; set; }        //SubQuery
        public decimal ValorAproximado { get; set; }
        public decimal? ValorFinal { get; set; } //SubQuery
    }
Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s