As vezes, principalmente durante os testes, precisamos popular o banco de dados com alguma massa, o hibernate oferece isso de forma extremamente fácil de duas maneiras, uma é criando um arquivo chamado import.sql em qualquer lugar do classpath.
Sim, apenas isso já basta para o hibernate executar esse script durante a criação da SessionFactory.
Outra maneira é através da propriedade “hibernate.hbm2ddl.import_files”.
Simples assim, porém, extremamente útil.

Hoje precisei realizar alguns testes de integração com o banco de dados, pesquisei um pouco comparei as abordagens e decidi pela utilização do DBUnit.
Com ele é possível popular a base de dados com um conjunto de dados pré-definidos antes da execução de cada teste, para isso ele faz uso de ‘datasets’ preenchidos por nós. Então vamos ver como fazer isso, configurar o hibernate, gerar os ‘datasets’, testar com DBUnit.
No meu caso, tenho uma uma aplicação standalone que conecta-se em um servidor MySql, então meu hibernate.cfg.xml e meu HibernateUtil.java ficaram assim:

[sourcecode language=”xml” wraplines=”false” collapse=”false” gutter=”false”]

<!DOCTYPE hibernate-configuration PUBLIC

”-//Hibernate/Hibernate Configuration DTD 3.0//EN”

“http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd”>

com.mysql.jdbc.Driver jdbc:mysql://192.168.0.2:3306/faceted?autoReconnect=true root org.hibernate.dialect.MySQLDialect create-drop <!– Classes anotadas –>

[/sourcecode]

[sourcecode language=”java” wraplines=”false” collapse=”false” gutter=”false”]

public class HibernateUtil {

private static final SessionFactory sessionFactory = buildSessionFactory();

private static SessionFactory buildSessionFactory() {

return new AnnotationConfiguration().configure().buildSessionFactory();

}

public static Session openSession(){

return HibernateUtil.getSessionFactory().openSession();

}

private static SessionFactory getSessionFactory() {

return sessionFactory;

}

public static Connection getConnection(Session session) {

final Connection[] connection = new Connection[1];

session.doWork(new Work() {

public void execute(Connection con) throws SQLException {

connection[0] = con;

}

});

return connection[0];

}

}

[/sourcecode]

Agora que conseguimos conectar com o banco de dados, vamos criar os datasets para realizarmos nosso primeiro teste com o DBUnit, para isso, vamos exportar os dados através de um exportados de datasets.

[sourcecode language=”java” wraplines=”false” collapse=”false” gutter=”false”]

public class DatasetExporter {

@Test

public void export() throws Exception {

generateDataSet(“Empresa”,”select * from Empresa”);

}

public void generateDataSet(String table, String query) throws Exception{

Session session = HibernateUtil.openSession();

Connection jdbcConnection = HibernateUtil.getConnection(session);

IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);

QueryDataSet dataSet = new QueryDataSet(connection);

dataSet.addTable(table, query);

FlatDtdDataSet.write(dataSet, new FileOutputStream(table+”.dtd”));

FlatXmlDataSet.write(dataSet, new FileOutputStream(table+”.xml”));

jdbcConnection.close();

}

}

[/sourcecode]

Você não precisa executa-lo com um teste unitário, o importante é entender que você precisa fornecer as queries para buscar os dados que você quer utilizar em seus testes e que dois arquivos serão criados, um xml com os dados e um dtd para validar os dados desse xml. Veja os arquivos gerados:

[sourcecode language=”xml” wraplines=”false” collapse=”false” gutter=”false”]

<!ELEMENT dataset (

Empresa*)>

<!ELEMENT Empresa EMPTY>

<!ATTLIST Empresa

id CDATA #REQUIRED

ativa CDATA #IMPLIED

nome CDATA #IMPLIED

[/sourcecode]

[sourcecode language=”xml” wraplines=”false” collapse=”false” gutter=”false”]

[/sourcecode]

Agora vamos enfim ao teste em si.

[sourcecode language=”java” wraplines=”false” collapse=”false” gutter=”false”]

public class EmpresaTest {

private static final String EMPRESA_DATASET = “dbunit/Empresa.xml”;

private Session session;

private IDatabaseConnection databaseConnection;

@Before

public void setUp() throws Exception {

session = HibernateUtil.openSession();

databaseConnection = new DatabaseConnection(HibernateUtil.getConnection(session));

DatabaseOperation.CLEAN_INSERT.execute(databaseConnection, getDataSet(EMPRESA_DATASET));

}

private IDataSet getDataSet(String datasetFile) throws Exception {

InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(datasetFile);

IDataSet dataset = new FlatXmlDataSet(inputStream);

return dataset;

}

@Test

public void test() throws Exception {

List empresas = session.createCriteria(Empresa.class).list();

Assert.assertTrue(!empresas.isEmpty());

}

}

[/sourcecode]

E para finalizar, as dependências:

[sourcecode language=”xml” wraplines=”false” collapse=”false” gutter=”false”]

mysql mysql-connector-java 5.1.27 test junit junit 4.11 test org.dbunit dbunit 2.4.5 test

[/sourcecode]

Em 1994, uma pesquisa denominada The Chaos Report foi realizada pelo Standish Group para identificar os motivos que levam um projeto de software ao fracasso. Essa pesquisa teve início baseado na comparação entre a construção de pontes e a criação de softwares, pontes geralmente são entregues no prazo, dentro do custo e sem falhas. Em contrapartida é muito comum que projetos de software sejam abortados, que ultrapassem o custo planejado ou que sejam finalizados com funcionalidades reduzidas. Baseado nessa comparação, foi identificado que o processo de construção de pontes progrediu devido ao fato de que quando uma ponte cai, uma investigação é iniciada, relatórios são escritos e as causas reveladas e divulgadas, diferentemente do que acontece quando um projeto de software fracassa.

A pesquisa realizada pelo Standish Group foi realizada em conjunto com 365 empresas responsáveis pelo desenvolvimento de 8380 projetos de software, essas empresas foram separadas em grandes (lucros acima de 500 milhões de dólares por ano), medias (lucros entre 200 e 500 milhões de dólares por ano) e pequenas(lucros entre 100 e 200 milhões de dólares por ano). Esse trabalho identificou que uma das maiores causas dos custos acima do esperado e perda do prazo de entrega foram os restarts, de cada 100, 94 foram reiniciados para tentar corrigir falhas dos mais diversos tipos.

Em média, os valores ultrapassaram em 189% os valores estimados inicialmente, para as grandes empresas esse valor ficou em 178%, para as médias 182% e 214% para as pequenas. Com relação ao tempo, no geral os projetos demoraram 222% a mais do que o esperado para serem entregues, 230% além do previsto para as grandes empresas, 202% para as médias e 239% para as pequenas. As features também não ficaram de fora, mesmo pagando e esperando mais do que o previsto somente 42% das funcionalidades foram entregues para as grandes empresas, 65% para as médias e 74% para as pequenas.

O estudo identificou e pontuou os itens de maior relevância no que diz respeito ao sucesso ou o fracasso de um projeto. A conclusão em ordem de importância foi a seguinte:

  1. Envolvimento do usuário
  2. Suporte executivo
  3. Requisitos claros
  4. Planejamento adequado
  5. Expectativas realísticas
  6. Iterações pequenas (“growing” ao invés de “developing”)
  7. Competência do time
  8. Gerenciamento correto
  9. Visão clara dos objetivos
  10. Trabalho duro / Time focado

Recentemente eu andei perguntando para outras pessoas como elas estudavam, talvez para poder comparar com o que eu faço, talvez para conhecer novos métodos, novas artimanhas 🙂 . Então resolvi escrever um post curto para dizer o que eu penso quando estou estudando.

Quando comecei a programar, os meus estudos não seguiam um padrão, eu estudava com os materiais disponíveis sem prestar muita atenção no que hoje eu considero serem os pontos importantes para o aprendizado de uma nova linguagem.

Para mim, quando se está aprendendo uma nova linguagem existem 3 pontos que devem ser considerados os pontos de atenção:

– O primeiro e mais importante é o modelo de abstração que a linguagem oferece.

– O segundo é a sintaxe em si.

– O terceiro é aprender sobre as bibliotecas padrão relacionadas a linguagem em questão.

Em seguida, para haver fluência precisamos entender os design patterns e expressões idiomáticas comumente utilizadas nessa linguagem.

Hoje em dia tento manter o foco nesses pontos, assim eu consigo entender um pouco melhor como a linguagem funciona e também fazer um paralelo com outras linguagens estudadas anteriormente.