domingo, 19 de fevereiro de 2012

TDD utilizando DBUnit

Executar testes unitários em métodos que acessam o banco de dados sempre geram dor de cabeça, porque precisamos garantir um estado esperado dos dados antes que o teste ocorra. testes que podem influenciar o banco de maneira que altere dados importantes para outros testes são outro problema.
Para evitar a necessidade de todo esse trabalho com SQL pra cá e pra lá para manter os dados no estado esperado, foi criado o framework DBUnit.
DBUnit é uma extensão do JUnit destinado a trabalhar com banco de dados, seu maior objetivo é colocar seu banco de dados em um estado conhecido entre as execuções de teste, para que os problema acima não ocorram e possamos confiar nos resultados de nossos testes.

O primeiro passo é baixar o arquivo jar do DBUnit, após coloca-lo no seu Build Path devemos criar um arquivo xml com os dados necessários para o seu teste, o modo mais simples que conheço é pedir para que o DBUnit leia uma ou mais tabelas e exporte-as para xml como no exemplo abaixo:

Como podemos ver, existe a possibilidade de especificar um critério para os dados exportados utilizando clausulas SQL.
Com o arquivo XML gerado podemos partir para os testes:

Na primeira linha do teste leio o nosso arquivo xml recém criado para que seja inserido seus dados no banco através do método insereDadosParaTeste, omiti o modo que obtenho a conexão com o banco porque essa parte varia muito da implementação que é utilizada no sistema, abaixo segue alguns exemplos que me deparei nos ultimos dias.

A operação CLEAN_INSERT limpa as tabelas relacionadas e insere os dados gravados no XML.
Por fim podemos executar os testes necessários tendo certeza que o banco de dados está do jeito que esperamos quando criamos o teste.

Ps: Lembre de tomar cuidado quando utilizar o getDelegate pois o retorno desse método depende de sua implementação, ou seja, o que funciona no tomcat, pode não funcionar no glassfish e o que funciona no hibernate pode não funcionar no eclipselink, maiores informações em Be careful while using EntityManager.getDelegate()

quinta-feira, 16 de fevereiro de 2012

Hibernate - melhorando a performance com Stateless Session

Trabalhar utilizando a conhecida Session em processos com muitos objetos é sempre muito custoso em termos de memória e velocidade, e as chances de se deparar com exceções de OutOfMemory são grandes.
Nesses momentos o recomendado pelo manual de referencia do Hibernate é a utilização da StatelessSession, este objeto não permite LazyInitialization, persistência em cascata, first-level cache entre outras funcionalidades, ficando muito mais próximo do JDBC.
Abaixo segue um exemplo básico que implementa a StatelessSession.

Nas pesquisas, tenho utilizado Stateless Session com Criteria ou HQL, dependendo da complexidade da pesquisa, nos momentos em que os dados retornados são apenas para visualização e após inserir e/ou recuperar algumas milhares de registros consegui perceber claramente as vantagens da StatelessSession.
Maiores informações sobre Stateless Session e batch processing no guia de referencia do Hibernate.