Dúvidas com utilização de tipos genéricos

4 respostas
bonfarj

O sistema que estou desenvolvendo na minha empresa faz uso intenso de tipos genéricos. Vejam este método:

public <E extends Entidade> E getObject(E entidade) throws HibernateException {

		@SuppressWarnings("unchecked")
		E myObject = (E) session.get(entidade.getClass(), entidade.getId());
		return myObject;
	}

A interface Entidade é implementada por todos as classes mapeadas no Hibernate. Se eu quiser recuperar no banco uma instância de Pessoa com o id 1, basta chamar getObject(pessoa), onde pessoa é um objeto da classe Pessoa com o id = 1.

Esse caso está ok. Vamos vejam este método:

public <E extends Entidade> List<E> listar(E entidade) throws NomusException {

		try {
			Criteria criteria = session.createCriteria(entidade.getClass());

			@SuppressWarnings("unchecked")
			List<E> entidades = criteria.list();

			return entidades;

		} catch(Exception e) {
			e.printStackTrace();
			throw new NomusException(e.getMessage());
		}
	}

Este método lista todos os registros de uma determinada entidade. Também passamos como parâmetro um objeto entidade, mas reparem que neste caso bastaria passar a classe da entidade para o session.createCriteria(Class persistentClass), não precisa do objeto inteiro. Hoje nós somos obrigados a chamar o método assim:

listar(new Pessoa())

Mas eu gostaria que fosse assim:

listar(Pessoa.class)

Poderíamos fazer isso:

public List listar(Class classeEntidade) throws NomusException {

		try {
			Criteria criteria = session.createCriteria(classeEntidade);

			List entidades = criteria.list();

			return entidades;

		} catch(Exception e) {
			e.printStackTrace();
			throw new NomusException(e.getMessage());
		}
	}

Mas assim perderíamos o benefício dos tipos genéricos. Alguém sabe como eu poderia fazer para permitir que seja passado como parâmetro apenas objetos da classe Class que implementem uma determinada interface (no caso Entidade)? Não vale checar apenas em tempo de execução, hehe!

abração, pessoal! ;)

4 Respostas

danieldestro

Só um comentário. Não poderia ser Serializable em vez de Entidade?

emmanuel.silva

Seria isso que você queria:

public &lt;T extends Entidade&gt; teste(Class&lt;T&gt; classe) {
        //codigo
    }

para usar o metodo seria…

teste(Pessoa.class)
bonfarj
danieldestro:
Só um comentário. Não poderia ser Serializable em vez de Entidade?

Bem lembrado, Entidade estende Serializable, vejam:

package br.com.nomus.modelo.entidade.interfaces;

import java.io.Serializable;

public interface Entidade extends Serializable {
	
	public int getId();
	public void setId(int id);
}

E emmanuel.silva, por mais incrível que possa parecer, eu havia testado ("testado") exatamente o que você falou, mas não funcionou! Por sorte, ao ver seu post, eu tentei novamente! Depois eu descobri por acaso o porquê de não ter funcionado: eu não havia salvo o arquivo com a modificação... :oops:

Valeu por abrir meus olhos para esta questão!

Muito obrigado mesmo, pessoal!!!

emmanuel.silva

hehe isso acontece;

Criado 28 de fevereiro de 2007
Ultima resposta 28 de fev. de 2007
Respostas 4
Participantes 3