[Resolvido] Hibernate: Problema com SQLQuery e campos com nomes iguais

Olá pessoal,

Estou com problemas para executar a seguinte SQLQuery no Hibernate. Ao executa-la recebo uma mensagem dizendo que a coluna ‘tx_nome’ não existe, mas se executo essa mesma query no banco ela funciona normalmente.

SELECT
    L.cp_lancamento_cereais_graos,
    L.nr_ticket,
    L.tx_nf_produtor,
    L.ce_empresa,
    P.tx_nome AS tx_nome_produtor,    
    PR.tx_nome AS tx_nome_proprural,
    PD.tx_nome AS tx_nome_produto,
    V.tx_nome AS tx_nome_variedade,
    M.tx_nome AS tx_nome_motorista,
    VI.tx_placa,    
    L.qt_peso_bruto,
    (L.qt_peso_bruto - L.qt_peso_liquido) AS qt_descontos,
    L.qt_peso_liquido
FROM
    view_lancamentos_cereais_graos AS L,
    produtores AS P,
    propriedades_rurais AS PR,
    veiculos AS VI,
    motoristas AS M,
    variedades AS V,
    produtos AS PD
WHERE
    L.ce_produtor = P.cp_produtor
    AND L.ce_propriedade_rural = PR.cp_propriedade_rural
    AND L.ce_veiculo = VI.cp_veiculo
    AND L.ce_motorista = M.cp_motorista
    AND L.ce_variedade = V.cp_variedade
    AND V.ce_produto = PD.cp_produto
ORDER BY
    L.ce_empresa,
    P.tx_nome,
    PR.tx_nome,
    PD.tx_nome,
    V.tx_nome

Tentei não renomear as colunas tx_nome, deixando assim:

SELECT
    L.cp_lancamento_cereais_graos,
    L.nr_ticket,
    L.tx_nf_produtor,
    L.ce_empresa,
    P.tx_nome,    
    PR.tx_nome,
    PD.tx_nome,
    V.tx_nome,
    M.tx_nome,
    VI.tx_placa,    
    L.qt_peso_bruto,
    (L.qt_peso_bruto - L.qt_peso_liquido) AS qt_descontos,
    L.qt_peso_liquido
FROM
    view_lancamentos_cereais_graos AS L,
    produtores AS P,
    propriedades_rurais AS PR,
    veiculos AS VI,
    motoristas AS M,
    variedades AS V,
    produtos AS PD
WHERE
    L.ce_produtor = P.cp_produtor
    AND L.ce_propriedade_rural = PR.cp_propriedade_rural
    AND L.ce_veiculo = VI.cp_veiculo
    AND L.ce_motorista = M.cp_motorista
    AND L.ce_variedade = V.cp_variedade
    AND V.ce_produto = PD.cp_produto
ORDER BY
    L.ce_empresa,
    P.tx_nome,
    PR.tx_nome,
    PD.tx_nome,
    V.tx_nome

Dessa maneira a query é executada, mas em todos os campos ‘tx_nome’ eu recebo o valor do campo ‘P.tx_nome’.

Se alguém puder me explicar o que o Hibernate está fazendo, ficarei grato :slight_smile:

Já tentou alterar o ORDER BY para as colunas renomeadas com AS ? Verifique usando o log se o sql chega a ser executado e o resultado.

Abraço,

Fred

Mostra o código onde estás a usar isso.

[quote=fre_d]Já tentou alterar o ORDER BY para as colunas renomeadas com AS ? Verifique usando o log se o sql chega a ser executado e o resultado.

Abraço,

Fred[/quote]

Tentei renomear novamente as colunas e fazer o ORDER BY pelo novo nome delas, mesmo assim não funcionou, deu o mesmo problema de quando eu apenas renomeava elas:
org.hibernate.exception.SQLGrammarException: could not execute query

Caused by: java.sql.SQLException: Column ‘tx_nome’ not found

Então executei sem renomear as colunas e agora ativei a opção show_sql no hibernate.cfg. A query é executada do mesmo jeito que a envio, mas quando faço um query.list() o array de objetos vem errado (como disse acima, todos os tx_nome iguais).

...
getSession().beginTransaction();
Query q = getSession().createSQLQuery(query);
List<Object[]> dados = q.list();
getSession().getTransaction().commit();
...

Onde a variável ‘query’ é uma String com a query que citei no primeiro post.

Se renomeares as colunas, onde ocorre o erro? Não me parece que seja aí…

Se renomeio as colunas não funciona, dispara a exceção que falei acima. Eu também achei estranho, mas se eu renomeio apenas uma coluna (ex: P.tx_nome AS tx_nome_produtor) já dispara a exceção na hora que vai executar.

Por enquanto eu criei uma view para essa consulta com os campos renomeados, ai consigo utilizar eles normalmente, mas eu gostaria de saber de onde vem esse problema…

Mas em que sítio é que dá exactamente esse erro? Mostra o stacktrace.

Achei que a view resolveria meus problemas, mas ao adicionar um WHERE na query recebo de novo o erro dizendo que a coluna tx_nome não existe, mas na view realmente não existe uma coluna tx_nome e nem na query que mando executar há alguma referência a essa coluna.

Agora, consigo executar a seguinte query:

SELECT 
    cp_lancamento_cereais_graos, 
    dt_lancamento, 
    nr_ticket, 
    tx_nf_produtor, 
    ce_empresa, 
    tx_nome_produtor, 
    tx_nome_proprural, 
    tx_nome_produto, 
    tx_nome_variedade, 
    tx_nome_motorista, 
    tx_placa, 
    qt_peso_bruto, 
    qt_descontos, 
    qt_peso_liquido 
FROM 
    view_est_lancamentos_cereais_graos

Mas se adicione um WHERE, a deixando assim:

SELECT 
    cp_lancamento_cereais_graos, 
    dt_lancamento, 
    nr_ticket, 
    tx_nf_produtor, 
    ce_empresa, 
    tx_nome_produtor, 
    tx_nome_proprural, 
    tx_nome_produto, 
    tx_nome_variedade, 
    tx_nome_motorista, 
    tx_placa, 
    qt_peso_bruto, 
    qt_descontos, 
    qt_peso_liquido 
FROM 
    view_est_lancamentos_cereais_graos
WHERE
    ce_produto = 2

Já não funciona e recebo a seguinte exceção (mesma que ocorria sem a view, como falei no começo do tópico):

org.hibernate.exception.SQLGrammarException: could not execute query
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
	at org.hibernate.loader.Loader.doList(Loader.java:2536)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
	at org.hibernate.loader.Loader.list(Loader.java:2271)
	at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:316)
	at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1842)
	at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:165)
	at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:157)
	at TestSQLQuery.main(TestSQLQuery.java:27)
Caused by: java.sql.SQLException: Column 'tx_nome' not found.
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
	at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1144)
	at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5610)
	at org.hibernate.type.descriptor.sql.VarcharTypeDescriptor$2.doExtract(VarcharTypeDescriptor.java:61)
	at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:249)
	at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234)
	at org.hibernate.loader.custom.CustomLoader$ScalarResultColumnProcessor.extract(CustomLoader.java:505)
	at org.hibernate.loader.custom.CustomLoader$ResultRowProcessor.buildResultRow(CustomLoader.java:451)
	at org.hibernate.loader.custom.CustomLoader.getResultColumnOrRow(CustomLoader.java:348)
	at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:639)
	at org.hibernate.loader.Loader.doQuery(Loader.java:829)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
	at org.hibernate.loader.Loader.doList(Loader.java:2533)
	... 7 more

E a classe que estou utilizando para fazer os testes:

public class TestSQLQuery {    
    public static void main(String[] args) {
        String query = "SELECT cp_lancamento_cereais_graos, dt_lancamento, nr_ticket, tx_nf_produtor, ce_empresa, "
                + "tx_nome_produtor, tx_nome_proprural, tx_nome_produto, tx_nome_variedade, tx_nome_motorista, "
                + "tx_placa, qt_peso_bruto, qt_descontos, qt_peso_liquido FROM view_est_lancamentos_cereais_graos "
                + "WHERE ce_produto = 2";        
        try {
            Session session = DAOGenerico.getSession();
            session.beginTransaction();
            Query q = session.createSQLQuery(query);
            q.list();
            session.getTransaction().commit();
        } catch(Exception ex) {
            DAOGenerico.getSession().getTransaction().rollback();
            ex.printStackTrace();            
        }
    }
}

Se executo essa query no banco, funciona normalmente.

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/querysql.html#d0e17495

Acho que não entendi muito bem…

O meu caso seria o 18.1.1 do manual pois não pretendo transformar o resultado desta query em uma lista de entidades. O manual também não diz que há problemas em renomear os campos em um query desde que seu resultado não seja transformado em uma entidade.

Então ainda continuo sem entender o que se passa na execução dessa query.

Edit:

Problema resolvido.
Aparentemente é um problema relacionado ao conector do MySQL e não tem a ver com o Hibernate.
Para solucionar alterei a propriedade hibernate.connection.url no hibernate.cfg, adicionei uma flag, a deixando assim:

<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sgt?useOldAliasMetadataBehavior=true</property>

Agora está tudo funcionando, pra quem quiser saber mais detalhes sobre o problema abaixo os links que consultei:
http://bugs.mysql.com/bug.php?id=35150
https://hibernate.onjira.com/browse/HHH-4174
http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html

Obrigado a todos que responderam ao tópico :slight_smile:

Vê o 18.1.4

[quote]Until now, the result set column names are assumed to be the same as the column names specified in the mapping document. This can be problematic for SQL queries that join multiple tables, since the same column names can appear in more than one table.[/qtuote]

[quote=pmlm]Vê o 18.1.4

Como eu disse acima, não queria trabalhar com entidades.

[ ]'s