Erro ao utilizar GenericDAO

DAO

[code]@SuppressWarnings(“unchecked”)
public class GenericDAO<T extends AbstractEntity> {

protected static Session session;
protected static Transaction transaction;

public GenericDAO() {
    session = HibernateUtil.getSessionFactory().openSession();
    if (session.isConnected()) {
        session = HibernateUtil.getSessionFactory().openSession();
    }

}

public T getById(Long id) throws Exception {
    try {
        Class&lt;?&gt; tipo = getTypeClass();
        return (T) session.byId(tipo); /*Aqui tenho exceção..*/
    } catch (Exception e) {
        throw new Exception();
    }
}

public void save(T entity) throws Exception {
    try {
        transaction = session.beginTransaction();
        session.persist(entity);
        transaction.commit();
    } catch (Exception e) {
        transaction.rollback();
        throw e;
    }
}

public void update(T entity) throws Exception {
    try {
        transaction = session.beginTransaction();
        session.merge(entity);
        transaction.commit();
    } catch (Exception e) {
        transaction.rollback();
        throw e;
    }
}

public void delete(T entity) throws Exception {
    try {
        transaction = session.beginTransaction();
        session.delete(entity);
        transaction.commit();
    } catch (Exception e) {
        transaction.rollback();
        throw e;
    }
}

public List&lt;T&gt; findAll() throws Exception {
    return session.createQuery((&quot;From &quot; + getTypeClass().getName())).list();
}

/**
 * Retorna novo criteria para entidade.
 *
 * @return novo criteria para entidade.
 */
protected Criteria novoCriteria() throws Exception {
    Class&lt;?&gt; tipo = getTypeClass();
    return session.createCriteria(tipo);
}

private Class&lt;?&gt; getTypeClass() throws Exception {
    Class&lt;?&gt; clazz = (Class&lt;?&gt;) ((ParameterizedType) this.getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
    return clazz;
}

}[/code]

AbstractEntity

[code]@MappedSuperclass
public class AbstractEntity {

private Long id;

@Id
@GeneratedValue
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

}[/code]

Funcionario

@Entity @Table(name = &quot;funcionario&quot;) public class Funcionario extends AbstractEntity {

O meu método getByid , não consegue executar o cast p/ classe funcionário, tenho a exceção:

Você chama diretamente um objeto do GenericDAO? Ou possui um specific DAO?

Então, neste caso eu não chamo apenas o genericdao…
tenho um dao especifico, e ele é criado desta forma:

[code]

public class UsuarioDAO extends GenericDAO<Funcionario> {

public UsuarioDAO() {
    super();
}[/code]

Cara, seu DAO genérico está tentando pegar o tipo da propriedade ID, usando reflexão, tentando obter os valores parametrizados.

Observe que seu DAO Genérico apenas aceita como valores genéricos a Entidade, e não o tipo de seu Field ID. Pra ajudar, o hibernate pode criar proxys em cima de suas entidades, dependendo das configurações de mapeamento, bagunçando ainda mais a definição do Objeto, por isso vc tem um Class Cast Exception ali.

O que recomendo, é que você informe diretamente o tipo de dados para a classe genérica, poupando problemas desnecessários. Um simples refactory:

[code]
class AbstractDAO<EntityType extends AbstractEntity, IDType extends Serializable> {

private Class entityType;
private Class idType;

public AbstractDAO(Class entityType, Class idType) {
this… = …;
}

} [/code]

public class UsuarioDAO extends AbstractDAO<Usuario, Long> {

public UsuarioDAO() {
super(Usuario.class, Long.class);
}

}

Algo como:

Farei desta forma que você disse…
aproveitando, tenho uma pequena duvida…
o código do construtor abaixo

public GenericDAO() { session = HibernateUtil.getSessionFactory().openSession(); }

Toda classe que extender meu genericDao, qunado instanciada vai abrir uma nova sessão ?
tentei usar o getcurrentsession, já pensando nisso… só que tenho uma exceção, algo do tipo…
não existem sessões no momento…

Não sou especialista na API nativa do Hibernate, mas você poderia construir um Util, algo do tipo:

public class HibernateUtil {
	
	private static final SessionFactory sessionFactory;

	static {
		try {
			sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
		} catch (Throwable ex) {
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static Session getSession() throws HibernateException {
		return sessionFactory.getCurrentSession() == null ? sessionFactory.openSession() : sessionFactory.getCurrentSession();
	}

	public static SessionFactory getSessionFactory() throws HibernateException {
		return sessionFactory;
	}
}

PS: Você já pensou em usar Spring? Ele tem excelente integração com hibernate, e pode automatizar a injeção de sesões, além de gerenciamento transacional declarativo, etc.