extraño error invalid column name en hibernate

2,694 views
Skip to first unread message

Edson Chavez

unread,
Jun 24, 2010, 3:48:44 PM6/24/10
to jav...@googlegroups.com
Hola a todos estoy desarrollando una aplicacion con hibernate y un query de hql me arroja errores de invalid column name lo curioso es que es dependiendo de lo que ponga en el select pues para otros casos si se ejecuta correctamente

he posteado el mismo error en el foro de hibernate https://forum.hibernate.org/viewtopic.php?f=1&t=1005438&p=2432293#p2432293

las entidades son: una entidad que represente aplicaciones con una tabla join de empleados esta tabla join tiene columnas para efectuar auditorias como fecha de registro, de modificacion etc, por ello es que la tabla intermedia se representa como un tipo de valor (no es una entidad) es decir tengo 3 clases: la clase aplicativo, la clase empleado y una clase intermedia(LiberadorContrata) que representa la tabla join entre aplicativos y empleados, efectuo el siguiente query hql:

List<Aplicativos>  aplicativos =   newSession.createQuery("select a from  Aplicativos a join a.liberadores l where a.idAplicativo = :idAplicativo and l.empleado.contrata.idContrata = :idContrata").setString("idAplicativo", idAplicativo).setString("idContrata", idContrata).list();

esta primera version funciona bastante bien, obtengo la lista de aplicativos sin embargo cuando modifico el query para en lugar de una lista de aplicativos obtener una lista de liberadores (el arreglo del tipo de valor) obtengo lo siguiente:

List<LiberadorContrata>  liberadores =   newSession.createQuery("select l from  Aplicativos a join a.liberadores l where a.idAplicativo = :idAplicativo and l.empleado.contrata.idContrata = :idContrata").setString("idAplicativo", idAplicativo).setString("idContrata", idContrata).list();

como pueden ver solo he cambiado la seccion select que ahora en lugar de obtener la lista de aplicativos obtendra la lista de liberadores, esta segunda version arroja la siguiente excepcion:
org.hibernate.exception.GenericJDBCException: could not execute query 

la que viene desde sql server:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: El nombre de columna col_0_1_ no es válido.

ahora bien al ver el sql que se generaba no estaba la columna col_0_1_ !!!

este es el sql generado: 


Hibernate: 
    select
        liberadore1_.idAplicativo as col_0_0_ 
    from
        dbo.Aplicativos aplicativo0_ 
    inner join
        dbo.ContratasLiberador liberadore1_ 
            on aplicativo0_.idAplicativo=liberadore1_.idAplicativo,
        dbo.ContratasEmpleados empleado2_ 
    where
        liberadore1_.idEmpleado=empleado2_.idEmpleado 
        and aplicativo0_.idAplicativo=? 
        and empleado2_.idContrata=?


como pueden ver en el sql generado no esta la columna que me dice que no se encuentra es mas la consola me muestra lo siguiente:
24-jun-2010 14:06:03 org.hibernate.type.NullableType nullSafeGet
INFO: could not read column value from result set: col_0_1_; El nombre de columna col_0_1_ no es válido.

no entiendo por que si funciona en un caso y en otro no, si bien ya funcionando la primera consulta puedo obtener el arreglo que quiero (es un atributo de la clase aplicativos) no es lo mas elegante si quiero directamente el arreglo de empleados y cuando quiera los arreglos de varios aplicativos tampoco me servira de mucho, en el post del foro de hibernate he incluido el codigo de los beans (mapeados por anotacion) la clase que realiza el query y un TestCase para Junit que efectua pruebas sobre los 2 métodos mostrando que el primero si pasa y el segundo no

si es de interes lo pondre aqui pero no quiero saturar la lista

espero alguien me pueda ayudar con este problema

saludos


Edson
http://www.sindominio.net/ayuda/preguntas-inteligentes.html
http://soyfreakytambiengeek.blogspot.com/ <-- Mi Blog ^^

Santiago Risaro

unread,
Jun 24, 2010, 4:07:35 PM6/24/10
to jav...@googlegroups.com
mmm probablemente el problema lo tengas en el mapping de la tabla de liberadores, el se trae el aplicativo y cuando va a buscar los liberadores aparece esa col_0_1_ que menciona la excepción y no matchea con ninguna de las columnas de tu tabla.

2010/6/24 Edson Chavez <edson...@gmail.com>
--
www.JavaSOS.com
Grupo de colaboración Java/J2ee para desarrolladores de habla hispana.

Fabricio

unread,
Jun 24, 2010, 4:11:16 PM6/24/10
to jav...@googlegroups.com
Hibernate esta usando un alias de la columan el cual es el que dice que no encuentra , probablemente sea un tema del dialecto para SQLServer o algo por el estilo

2010/6/24 Edson Chavez <edson...@gmail.com>
--
www.JavaSOS.com
Grupo de colaboración Java/J2ee para desarrolladores de habla hispana.



--
Saludos.
Fabricio Tuosto

Edson Chavez

unread,
Jun 24, 2010, 4:31:14 PM6/24/10
to jav...@googlegroups.com
Hola Santiago , Fabricio

el arreglo esta como fetch.EAGER por lo que al cargar la entidad aplicativo se trae todos los liberadores de la tabla join en ambos casos tanto el que si se efectua correctamente como el que no, copio mis clases mapeadas el codigo que efectua las consultas y una prueba usando junit para aclarar el caso:

package domain;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;

import org.hibernate.annotations.CollectionOfElements;



@Entity
public class Aplicativos {
private String idAplicativo;
private String aplicativo;
private String activo;
private List <LiberadorContrata> liberadores = new ArrayList<LiberadorContrata>();

public Aplicativos(){
super();
}
@Id
public String getIdAplicativo() {
return idAplicativo;
}
public void setIdAplicativo(String idAplicativo) {
this.idAplicativo = idAplicativo;
}
public String getAplicativo() {
return aplicativo;
}
public void setAplicativo(String aplicativo) {
this.aplicativo = aplicativo;
}
public String getActivo() {
return activo;
}
public void setActivo(String activo) {
this.activo = activo;
}
 
@CollectionOfElements(fetch = FetchType.EAGER)
@JoinTable (name="ContratasLiberador", joinColumns = @JoinColumn(name = "idAplicativo"))
public List<LiberadorContrata> getLiberadores() {
return liberadores;
}


public void setLiberadores(List<LiberadorContrata> liberadores) {
this.liberadores = liberadores;
}
}


ahora la clase que representa la tabla join con los liberadores:
como puede verse el fetxh es un fetchType.Eager por lo que la lista se carga en el momento de hacer la consulta siempre. no solo cuando hago el select pidiendo especificamente que traiga el arreglo de liberadores


package domain;

import javax.persistence.*;

import org.hibernate.annotations.Parent;

@Embeddable
public class LiberadorContrata {
private Aplicativos aplicativo;
private Empleado empleado;
private String fechaRegistro;
private String usuarioRegistra;
private String activo;
@Parent
public Aplicativos getAplicativo() {
return aplicativo;
}

public void setAplicativo(Aplicativos aplicativo) {
this.aplicativo = aplicativo;
}

@ManyToOne
@JoinColumn(name = "idEmpleado", nullable= false, updatable= false)
public Empleado getEmpleado() {
return empleado;
}
public void setEmpleado(Empleado empleado) {
this.empleado = empleado;
}
@Column
public String getFechaRegistro() {
return fechaRegistro;
}
public void setFechaRegistro(String fechaRegistro) {
this.fechaRegistro = fechaRegistro;
}
@Column
public String getUsuarioRegistra() {
return usuarioRegistra;
}
public void setUsuarioRegistra(String usuarioRegistra) {
this.usuarioRegistra = usuarioRegistra;
}
@Column
public String getActivo() {
return activo;
}
public void setActivo(String activo) {
this.activo = activo;
}
}

esta clase contiene un atributo que representa a los empleados y campos de auditoria 

por ultimo una clase dummy (la clase real tiene mas referencias que no importan para lo que esta sucediendo) que representa al empleado

package domain;

import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table (name="ContratasEmpleados")
public class Empleado {
private String idEmpleado;
private String nombre;


public Empleado(){
super();
}
@Id
public String getIdEmpleado() {
return idEmpleado;
}
public void setIdEmpleado(String idEmpleado) {
this.idEmpleado = idEmpleado;
}
public String getNombre() {
return empleado;
}
public void setNombre(String empleado) {
this.empleado = empleado;
}
}

a continuacion la clase que implementa los metodos que efectuaran los querys 

package dao.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.hibernate.Session;
import org.hibernate.Transaction;

import AplicativosDao;
import domain.*;
import util.HibernateUtil;

public class AplicativosDaoImpl implements AplicativosDao {

public Aplicativos[] getAllAplicativos(){
Session newSession = HibernateUtil.getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
Aplicativos[] aplicativos =  (Aplicativos[]) newSession.createQuery("from Aplicativos").list().toArray(new Aplicativos[0]);
newTransaction.commit();
newSession.close();
HibernateUtil.shutdown();
return aplicativos ;
}
public List<Aplicativos> getAplicativos( String idAplicativo, String idContrata){
Session newSession = HibernateUtil.getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List<Aplicativos>  aplicativos =   newSession.createQuery("select a from  Aplicativos a join a.liberadores l where a.idAplicativo = :idAplicativo and l.empleado.contrata.idContrata = :idContrata").setString("idAplicativo", idAplicativo).setString("idContrata", idContrata).list();
newTransaction.commit();
newSession.close();
HibernateUtil.shutdown();
return aplicativos;
}
public List<LiberadorContrata> getLiberadores( String idAplicativo, String idContrata){
Session newSession = HibernateUtil.getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List<LiberadorContrata>  liberadores =   newSession.createQuery("select l from  Aplicativos a join a.liberadores l where a.idAplicativo = :idAplicativo and l.empleado.contrata.idContrata = :idContrata").setString("idAplicativo", idAplicativo).setString("idContrata", idContrata).list();
newTransaction.commit();
newSession.close();
HibernateUtil.shutdown();
return liberadores;
}
}

Como puede verse tanto el metodo getAplicativos como getLiberadores efectuan el mismo query solo se cambia la seccion del select 

por ultimo un caso de prueba donde se llaman a los dos metodos el primero obtiene el aplicativo, puede entrar a su arreglo de liberadores y obtener el nombre del empleado y lo imprime correctamente, por lo que toda la estructura se carga correctamente

el segundo test efectua el mismo codigo solo cambia la llamada al query (ahora prueba con el que intenta obtener el arreglo de libradores y no el aplicativo) y lanza los errores que indique en mi correo previo Esto esta de acuerdo a lo que indicabas Fabricio? o el hecho del alias para la columna es solo para la seccion select?

package dao.impl;

import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;
import domain.*;

public class AplicativosDaoImplTest {

@Test
public void testGetAplicativos() {
AplicativosDaoImpl aplicativosDao = new AplicativosDaoImpl();

List<Aplicativos> aplicativos = aplicativosDao.getAplicativos("1", "1");
assertTrue(aplicativos.size()>0 );
LiberadorContrata liberador = aplicativos.get(0).getLiberadores().get(0);
System.out.println(liberador.getEmpleado().getNombre());

}

@Test
public void testGetLiberadores() {
AplicativosDaoImpl aplicativosDao = new AplicativosDaoImpl();

List<LiberadorContrata> liberadores = aplicativosDao.getLiberadores("1", "1");
assertTrue(liberadores.size()>0 );
LiberadorContrata liberador = liberadores.get(0);
System.out.println(liberador.getEmpleado().getNombre());

}
}


espero esto aclare el caso que tengo

Jorge Medina

unread,
Jun 24, 2010, 5:31:50 PM6/24/10
to jav...@googlegroups.com
¿Se puede realizar un query que regrese objectos que no son entidades ?

-Jorge


2010/6/24 Edson Chavez <edson...@gmail.com>:

Jorge Medina

unread,
Jun 24, 2010, 5:44:40 PM6/24/10
to jav...@googlegroups.com
Quiza?

select elements(a.liberadores) from ...

2010/6/24 Jorge Medina <cerebrote...@gmail.com>:

Edson Chavez

unread,
Jun 24, 2010, 5:50:28 PM6/24/10
to jav...@googlegroups.com
Jorge

Excelente aporte, solucionaste el problema!!!

cambien el codigo de la consulta como sugeriste:

List<LiberadorContrata>  liberadores =   newSession.createQuery("select Elements(a.liberadores) from  Aplicativos a join a.liberadores l where a.idAplicativo = :idAplicativo and l.empleado.contrata.idContrata = :idContrata").setString("idAplicativo", idAplicativo).setString("idContrata", idContrata).list();
seguire haciendo pruebas para validar que traiga exactamente lo que necesito pero de momento ya no ejecuta excepciones y el test que habia hecho paso correctamente

esto responde la pregunta previa que hiciste: si se pueden retornar objetos que no son entidades
Reply all
Reply to author
Forward
0 new messages