Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

NHibernate + Firebird 2.5

Realizei os passos do capítulo 4 utilizando o firebird 2.5. Ao executar o código:

ISession session = NHibernateHelper.AbreSession();

            String hql = "select p.Categoria as Categoria, count(p) as NumerosDeProdutos from Produto p group by p.Categoria";
            IQuery query = session.CreateQuery(hql);
            query.SetResultTransformer(Transformers.AliasToBean<ProdutosPorCategoria>());
            IList<ProdutosPorCategoria> resultado = query.List<ProdutosPorCategoria>();




            session.Close();


            Console.Read();

ocorre a seguinte exception:

NHibernate.Exceptions.GenericADOException was unhandled
  HResult=-2146232832
  Message=could not execute query
[ select produto0_.CategoriaId as col_0_0_, count(produto0_.Id) as col_1_0_, categoria1_.Id as Id2_, categoria1_.Nome as Nome2_ from Produto produto0_ inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id group by produto0_.CategoriaId ]
[SQL: select produto0_.CategoriaId as col_0_0_, count(produto0_.Id) as col_1_0_, categoria1_.Id as Id2_, categoria1_.Nome as Nome2_ from Produto produto0_ inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id group by produto0_.CategoriaId]
  Source=NHibernate
  SqlString=select produto0_.CategoriaId as col_0_0_, count(produto0_.Id) as col_1_0_, categoria1_.Id as Id2_, categoria1_.Nome as Nome2_ from Produto produto0_ inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id group by produto0_.CategoriaId
  StackTrace:
       em NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes)
       em NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
       em NHibernate.Impl.SessionImpl.List(String query, QueryParameters queryParameters, IList results)
       em NHibernate.Impl.SessionImpl.List[T](String query, QueryParameters parameters)
       em NHibernate.Impl.QueryImpl.List[T]()
       em Loja.Program.Main(String[] args) na c:\Users\mmarcos\Desktop\Alura-NHibernate\Loja\Loja\Program.cs:linha 82
       em System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       em System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       em Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       em System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       em System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       em System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       em System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       em System.Threading.ThreadHelper.ThreadStart()
  InnerException: FirebirdSql.Data.FirebirdClient.FbException
       HResult=-2147467259
       Message=Dynamic SQL Error
SQL error code = -104
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
       Source=FirebirdSql.Data.FirebirdClient
       ErrorCode=335544569
       SQLSTATE=42000
       StackTrace:
            em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior)
            em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteDbDataReader(CommandBehavior behavior)
            em System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
            em NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
            em NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session)
            em NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
            em NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
            em NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
       InnerException: FirebirdSql.Data.Common.IscException
            HResult=-2146233088
            Message=Dynamic SQL Error
SQL error code = -104
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
            Source=FirebirdSql.Data.FirebirdClient
            ErrorCode=335544569
            IsWarning=false
            SQLSTATE=42000
            StackTrace:
                 em FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ProcessResponse(IResponse response)
                 em FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ReadResponse()
                 em FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ReadGenericResponse()
                 em FirebirdSql.Data.Client.Managed.Version11.GdsStatement.Prepare(String commandText)
                 em FirebirdSql.Data.FirebirdClient.FbCommand.Prepare(Boolean returnsSet)
                 em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior, Boolean returnsSet)
                 em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior)
            InnerException:

para ser mais preciso, o a exception supracitada ocorre nesta linha de código:

IList<ProdutosPorCategoria> resultado = query.List<ProdutosPorCategoria>();

Obrigado.

4 respostas

Olá Maurício

Repare que na sql gerada pelo NHibernate estamos executando um GroupBy pela coluna CategoriaId do produto.

select 
  produto0_.CategoriaId as col_0_0_,
  count(produto0_.Id) as col_1_0_,
  categoria1_.Id as Id2_,
  categoria1_.Nome as Nome2_ 
from 
  Produto produto0_ 
  inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id 
group by 
  produto0_.CategoriaId

E estamos selecionando todos os campos da categoria no select da query, normalmente só podemos selecionar os campos que estão no group by ou funções agregadas quando fazemos uma query agrupada, porém o mysql implementa uma extensão da SQL que permite o select de campos que estão fora do group by e por isso a query funciona no mysql e não no firebird.

Para os bancos que não suportam a extensão da SQL, podemos modificar a HQL para listar todos os campos da categoria no group by:

String hql = "select p.Categoria as Categoria, count(p) as NumerosDeProdutos from Produto p group by p.Categoria.Id, p.Categoria.Nome";

Com essa modificação, a SQL gerada pelo NHibernate fará um select apenas de campos que estão no group by e por isso ela funcionará da forma esperada.

Olá Victor, agradeço por sua atenção, todavia, mesmo após ter procedido com a alteração do string do HQL, o erro persiste.

 ISession session = NHibernateHelper.AbreSession();

            String hql = "select p.Categoria as Categoria, count(p) as NumerosDeProdutos from Produto p group by p.Categoria.Id, p.Categoria.Nome";
            IQuery query = session.CreateQuery(hql);
            query.SetResultTransformer(Transformers.AliasToBean<ProdutosPorCategoria>());
            IList<ProdutosPorCategoria> resultado = query.List<ProdutosPorCategoria>();

            session.Close();
            Console.Read();

exception:

NHibernate.Exceptions.GenericADOException was unhandled
  HResult=-2146232832
  Message=could not execute query
[ select produto0_.CategoriaId as col_0_0_, count(produto0_.Id) as col_1_0_, categoria1_.Id as Id2_, categoria1_.Nome as Nome2_ from Produto produto0_ inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id, Categoria categoria2_ where produto0_.CategoriaId=categoria2_.Id group by produto0_.CategoriaId , categoria2_.Nome ]
[SQL: select produto0_.CategoriaId as col_0_0_, count(produto0_.Id) as col_1_0_, categoria1_.Id as Id2_, categoria1_.Nome as Nome2_ from Produto produto0_ inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id, Categoria categoria2_ where produto0_.CategoriaId=categoria2_.Id group by produto0_.CategoriaId , categoria2_.Nome]
  Source=NHibernate
  SqlString=select produto0_.CategoriaId as col_0_0_, count(produto0_.Id) as col_1_0_, categoria1_.Id as Id2_, categoria1_.Nome as Nome2_ from Produto produto0_ inner join Categoria categoria1_ on produto0_.CategoriaId=categoria1_.Id, Categoria categoria2_ where produto0_.CategoriaId=categoria2_.Id group by produto0_.CategoriaId , categoria2_.Nome
  StackTrace:
       em NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes)
       em NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters)
       em NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
       em NHibernate.Impl.SessionImpl.List(String query, QueryParameters queryParameters, IList results)
       em NHibernate.Impl.SessionImpl.List[T](String query, QueryParameters parameters)
       em NHibernate.Impl.QueryImpl.List[T]()
       em Loja.Program.Main(String[] args) na c:\Users\mmarcos\Desktop\Alura-NHibernate\Loja\Loja\Program.cs:linha 85
       em System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       em System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       em Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       em System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       em System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       em System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       em System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       em System.Threading.ThreadHelper.ThreadStart()
  InnerException: FirebirdSql.Data.FirebirdClient.FbException
       HResult=-2147467259
       Message=Dynamic SQL Error
SQL error code = -104
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
       Source=FirebirdSql.Data.FirebirdClient
       ErrorCode=335544569
       SQLSTATE=42000
       StackTrace:
            em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior)
            em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteDbDataReader(CommandBehavior behavior)
            em System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
            em NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
            em NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session)
            em NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
            em NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
            em NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
       InnerException: FirebirdSql.Data.Common.IscException
            HResult=-2146233088
            Message=Dynamic SQL Error
SQL error code = -104
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)
            Source=FirebirdSql.Data.FirebirdClient
            ErrorCode=335544569
            IsWarning=false
            SQLSTATE=42000
            StackTrace:
                 em FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ProcessResponse(IResponse response)
                 em FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ReadResponse()
                 em FirebirdSql.Data.Client.Managed.Version10.GdsDatabase.ReadGenericResponse()
                 em FirebirdSql.Data.Client.Managed.Version11.GdsStatement.Prepare(String commandText)
                 em FirebirdSql.Data.FirebirdClient.FbCommand.Prepare(Boolean returnsSet)
                 em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteCommand(CommandBehavior behavior, Boolean returnsSet)
                 em FirebirdSql.Data.FirebirdClient.FbCommand.ExecuteReader(CommandBehavior behavior)
            InnerException:

grato pela atenção!

solução

Olá Maurício

Tente essa HQL:

select c as Categoria, count(p) 
from Produto p join p.Categoria c 
group by c.Id, c.Nome

Olá Victor, obrigado novamente!

Segue a HQL, somente adicionei o alias no count(p), veja:

String hql = "select c as Categoria, count(p) as NumerosDeProdutos from Produto p join p.Categoria c group by c.Id, c.Nome";

Agradeço sua ajuda e colaboração.

Abraços.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software