Spring com JPA [Resolvido]

  • RESPOSTA: O problema aconteceu porque eu coloquei .jar duplicado… Como eu estava usando aplicação web, já havia um jta.jar na pasta lib do tomcat! Erro primário!!

Beleza, pessoal!!

Eu já consegui fazer uma aplicação utilizando JPA, entretanto eu estou tendo que codificar os commits, abrir sessão e tudo mais…
Eu fiquei sabendo que o Spring 2.5 pode cuidar da transação para mim, como isso funciona?

Tentei utilizar o spring, só que deu um erro que eu não sei o que pode ser.
Eu estou utilizando o Eclipse como IDE, e o Hibernate como ferramenta ORM. Sem o Spring, a aplicação funciona normalmente, quando eu faço as alterações para utilizar o spring dá erro!

vejam o applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="springPU" />
	</bean>
	
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
	
	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>
	
	<tx:annotation-driven/>
	
	<bean name="cidadeDao" class="br.com.spring.dao.imp.CidadeDaoImp" />
	<bean name="clienteDao" class="br.com.spring.dao.imp.ClienteDaoImp" />

</beans>

aqui está o meu DaoGenerico:

@Transactional(readOnly=true, propagation=Propagation.REQUIRED)
public class GenericoPDVDaoImp<T, ID extends Serializable> implements GenericoPDVDao<T,ID> {

//	private EntityManagerFactory entityManagerFactory;
    private EntityManager entityManager;
//    private EntityTransaction tx;
	
	private final Class<T> oClass;
	
	public GenericoPDVDaoImp(){
		
//		entityManagerFactory = Persistence.createEntityManagerFactory("springPU");
		this.oClass = (Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
		
	}

    public EntityManager getEntityManager() {
        
    	if(entityManager==null)
            throw new IllegalStateException("Erro");
        
        return entityManager;
        
    }

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

	public Class getObjectClass() {
		return this.oClass; 
	}

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
	public T salvar(T object) {
        
//        this.setEntityManager(entityManagerFactory.createEntityManager());
//        tx=this.getEntityManager().getTransaction();
//		tx.begin();
        this.getEntityManager().clear();
        this.getEntityManager().persist(object);

//		tx.commit();
//		this.getEntityManager().close();
		
		return object;
	}

	public T pesquisarPorId(ID id) {
		
//		this.setEntityManager(entityManagerFactory.createEntityManager());
                
		T algo = (T) this.getEntityManager().find(oClass, id);
		
//		this.getEntityManager().close();
                
		return algo;
	}

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
	public T atualizar(T object) {
		
//        this.setEntityManager(entityManagerFactory.createEntityManager());
//		tx=this.getEntityManager().getTransaction();
//		tx.begin();
                
    	this.getEntityManager().merge(object);

//		tx.commit();
//        this.getEntityManager().close();

		return object;

	}

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
	public void excluir(T object) {
		
//    	this.setEntityManager(this.entityManagerFactory.createEntityManager());
//        tx=this.getEntityManager().getTransaction();
//		tx.begin();
		
        object = this.getEntityManager().merge(object);
        this.getEntityManager().remove(object);

//		tx.commit();
//		this.getEntityManager().close();

	}

	public T pesqParam(String query, Map<Integer, Object> params){
		
//		this.setEntityManager(entityManagerFactory.createEntityManager());
                
		Query q = this.getEntityManager().createQuery(query);
		
		for(Integer chave: params.keySet()){
			q.setParameter(chave, params.get(chave));
		}		
			
			T elemento = (T) q.getSingleResult();
			
//			this.getEntityManager().close();
			
			return elemento;

	}

	public List<T> todos() {
		
//		this.setEntityManager(entityManagerFactory.createEntityManager());
		
		String queryS = "SELECT obj FROM "+oClass.getSimpleName() + " obj";
		ArrayList<T> lista = (ArrayList<T>) this.getEntityManager().createQuery(queryS).getResultList();
		
//		this.getEntityManager().close();
		
		return lista;
	}

	
	public List<T> listPesqParam(String query, Map<Integer, Object> params) {
		
//		this.setEntityManager(entityManagerFactory.createEntityManager());
		
		Query q = this.getEntityManager().createQuery(query);
		
		for(Integer chave: params.keySet()){
			q.setParameter(chave, params.get(chave));
		}

			ArrayList<T> lista = (ArrayList<T>) q.getResultList();
			
//			this.getEntityManager().close();
			
			return lista;
		
	}

	
}

basicamente eu estou tentando usar o Spring primeiro em uma classe de test!

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:**/applicationContext.xml"})
public class TestCidadeDao {

	private CidadeDao cidadeDao;

	@Autowired
	public void setCidadeDao(CidadeDao cidadeDao) {
		this.cidadeDao = cidadeDao;
	}
	
	private Integer id = 6;
	
	@Test
	public void testSalvar() {
		Cidade cidade = null;
		cidade = this.cidadeDao.salvar(getCidade());
		
		assertNotNull(cidade);
		assertEquals(getCidade().getNome(), cidade.getNome());
		
	}

	@Test
	public void testPesquisarPorId() {
		
		Cidade cidade = null;
		
		cidade = this.cidadeDao.pesquisarPorId(id);
		
		assertNotNull(cidade);
		assertEquals("Uberaba", cidade.getNome());
		
	}

	@Test
	public void testAtualizar() {

		Cidade cidade = this.cidadeDao.pesquisarPorId(id);
		cidade.setNome("Uberlandia");
		
		cidade = this.cidadeDao.atualizar(cidade);
		
		assertNotNull(cidade);
		assertEquals("Uberlandia", cidade.getNome());
		
	}

	@Test
	public void testPesqParam() {
		
		Map<Integer, Object> params = new HashMap<Integer, Object>();
		params.put(1, "Uberlandia");
		
		Cidade cidade = this.cidadeDao.pesqParam("select c from Cidade c where c.nome like ? ", params);
		
		assertNotNull(cidade);
		assertEquals("Uberlandia", cidade.getNome());
		
	}

	@Test
	public void testTodos() {
		
		List<Cidade> cidades = this.cidadeDao.todos();
		
		assertNotNull(cidades);
		assertEquals("Uberlandia", cidades.get(0).getNome());
		
	}

	@Test
	public void testListPesqParam() {
		
		Map<Integer, Object> params = new HashMap<Integer, Object>();
		params.put(1, "Uberlandia");
		
		List<Cidade> cidades = this.cidadeDao.listPesqParam("select c from Cidade c where nome like ? ", params);
		
		assertNotNull(cidades);
		assertEquals("Uberlandia", cidades.get(0).getNome());
	}

	@Test
	public void testExcluir() {
		
		Cidade cidade = this.cidadeDao.pesquisarPorId(id);
		this.cidadeDao.excluir(cidade);
		
		assertNull(this.cidadeDao.pesquisarPorId(id));
		
	}
	
	public Cidade getCidade(){
		
		Cidade cidade = new Cidade();
		cidade.setNome("Uberaba");
		
		return cidade;
		
	}

}

valeu!

Vale a pena dar uma lida em http://static.springframework.org/spring/docs/2.5.x/reference/transaction.html#transaction-declarative

Basicamente, deve-se criar um bean de transaction manager, que muda dependendo se vai usar JDBC simples, Hibernate, iBatis ou JPA. Com JPA é assim:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="emf"/>
</bean>

onde emf é o bean que referencia um EntityManagerFactory.

Depois, usa-se a tag

<tx:annotation-driven transaction-manager="transactionManager"/>

para abilitar as anotações de transações.

É isso.

DAO genérico excelente que adotamos nos projetos atualmente, onde trabalho, aprendi no livro Dominando Java Server Faces e Facelets Utilizando Spring 2.5, Hibernate e JPA.
Porém, não o recomendo para que não tem noções de Spring, Hibernate ou JPA. O DAO é com JPA, super genérico e com poucas linhas. Recomendo.

O meu problema é que eu não estou conseguindo usar o Spring, a parte de persistência está funcinando 100%!

Quero dizer, se eu tiro o Spring, funciona, se eu tento colocar não dá certo!