Crud

Olá pessoal,

Eu esotu desenvolvendo o meu primeiro CRUD genérico em JPA e estou com uma dúvida que não estou conseguindo resolver,
para atualizar ou remove um objeto no JPA eu preciso encontra-lo primeiro pelo seu ID e depois atualiza-lo ou exclui-lo neh verdade?

O problema é que eu não estou conseguindo fazer a busca pelo ID usando o JPA

public T procurarPorId(Integer id) throws Exception {         
        T object = null;      
        try{                 
            object = (T) em.find(object.getClass(), id);             
            return object;
        }
        catch(Exception e){             
            throw e;  
        }  
        finally {
            em.close();
        }
    } 

dá uma NullPointerException em T object = null; mas como estou usando generic eu não posso instânciar object e por isso dá uma NullPointerException.

Será que alguém poderia me dar uma ajuda?

[]'s.

Eu já olhei os links:

http://www.universidadejava.com.br/docs/exemplodedaocrudutilizandojpa
http://www.guj.com.br/java/72576-opinem-sobre-meu-dao-generico
http://www.guj.com.br/java/140871-dao-impl-com-fluent-interface–

Mas não adiantou e até agora não consegui implementar a busca por ID usando o JPA.

Será que alguém poderia me dar uma ajuda?

[]'s.

Oi.

Ricardo, se está usando Generics porque precisa converter o Generic em Objetc e retornar esse Object sendo que o seu método retorna um Generic?
Algo tão importante quanto isso, é se você já leu sobre o método find do EntityManager.

A classe que é informando no método find deve ser um @Entity e representa a entidade que desejas retornar, sendo assim, se faz necessário que informe o que está buscando. Creio que se quer algo tão genérico não deves usar o find, mas fazer como uma query qualquer.

Abraços.

Só para deixar claro o que eu quero dizer, se você envia uma classe “genérica” ao find, como ele vai descobrir qual tabela ele deve consultar através da PK? Por mágica que não será, concorda? :smiley:

Uma sugestão, é você alterar a assinatura do seu método, assim:

public T procurarPorId(Class clazz, Integer id) throws Exception { try{ return em.find(clazz, id); } catch(Exception e){ throw e; } finally { em.close(); } }

Pronto, podes passar em qualquer parte do teu sistema a classe que deseja buscar pela PK :slight_smile:
Abraços.

Ricardo,dá uma olhada nesse que funciona:

Interface:

public interface GenericDAO <T,ID extends Serializable> {
	public Class<T>getObjectClass();
	public T findById(ID id);
	public T salvar(T object) ;
	public T atualizar(T object);
	public T excluir(T object);
	public List<T> todos(String ordem);
}

Impl:

public  class GenericDAOImp<T,ID extends Serializable> implements GenericDAO<T, ID> {
	@PersistenceContext
	private EntityManager entityManager;
	private final Class<T> classePersistente;

	public GenericDAOImp(){
		this.classePersistente = (Class<T>)
		((ParameterizedType)getClass().getGenericSuperclass())
		.getActualTypeArguments()[0];
	}

	public Class<T> getClassePersistente() {
		return classePersistente;
	}

	protected final Criteria criaCriteria() {
		return criaSession().createCriteria(getClassePersistente());
	}

	public final Session criaSession() {
		return  (Session)getEntityManager().getDelegate();
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	@Override
	public Class<T> getObjectClass() {
		return this.classePersistente;
	}

	@Override 
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED) 
	public T salvar(T object)  {
		getEntityManager().clear();
		try {
			getEntityManager().persist(object);
		}catch(Exception e){
			e.printStackTrace();
		}
		return object;
	}

	@SuppressWarnings("unchecked")       
	public List<T> todos(String ordem){ 
		StringBuffer queryS = new StringBuffer("SELECT obj FROM "+classePersistente.getSimpleName()+" obj "); 
		if(ordem!=null){
			queryS.append("order by "+ordem);
		}
		Query query = getEntityManager().createQuery(queryS.toString()); 
		return query.getResultList(); 
	}

	@Override 
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED) 
	public T atualizar(T object) {
		getEntityManager().merge(object);
		return null;
	}

	@Override 
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED) 
	public T excluir(T object) {
		try {
			object = getEntityManager().merge(object);
			getEntityManager().remove(object);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED) 
	public T findById(ID id) {
		return getEntityManager().find(getClassePersistente(), id);
	}

Falaaa nel e raf4ever, eu estou fazendo assim e modifiquei o meu código
de acordo com o q o nel falou

public T procurarPorId(Class clazz,Integer id) throws Exception {         
        T object = null;      
        try{                 
            object = (T) em.find(clazz, id);             
            return object;
        }
        catch(Exception e){             
            throw e;  
        }  
        finally {
            em.close();
        }
    }  

e para testar eu faço o seguinte

public class TesteBolsista {
    
    public static void main(String[] args){

        TesteBolsista testes = new TesteBolsista();

//        testes.salvar();
//        testes.listar();
        //testes.atualizar();
        testes.procurar();
        //testes.excluir();
 
    }
    
...
    private void procurar(){
                
        try {
            DAOGenerico bolsistaDAO =  new DAOGenerico();
            Bolsista bolsista = (Bolsista) bolsistaDAO.procurarPorId(Bolsista.class, 2);
            System.out.println(bolsista);
        } 
        catch (Exception ex) {
            ex.printStackTrace();
        }
        
    }
...
}

Agora preciso testar o meu excluir e o meu atualizar alguém conhece alguma forma mais prática e melhor de testar o CRUD?

[]'s.

Devemos entender que deu certo? :slight_smile:
E o pessoal costuma utilizar um componente chamado JUnit para realização de testes.

É muito interessante, é uma API via Annotation e que você pode montar vários ambientes de testes.
Mas precisa de paciência e atenção para montar os testes.

Abraços.

Valeu nel e raf4ever e MUITO OBRIGADO pela ajuda de vc’s,

Agora deu certo aqui :smiley:

Abração.