Lendo XML & Populando no BD via Hibernate

olá Pessoal,

O post de hoje é como popular um banco de dados tendo os dados em um arquivo XML. Se ainda não passou por esse requisito no seu trabalho, não se preocupe que o momento vai chegar. Há várias formas de fazer a leitura do arquivo XML e popular o banco, para o post, escolhi o Xstream e o Hibernate, que já uso o Hibernate por default e o Xstream é de fato uma boa API. Há também a SAPX, que não cheguei a testar.

Lets go…

Requisitos

  • Java 5/superior
  • Hibernate 3.x/Superior
  • Eclipse IDE
  • Xstream : faça o download da API
  • MySql 5

Iniciando

Para inicio você precisa criar um Java Project no seu Eclipse, e ter as bibliotecas do Hibernate adicionadas ao projeto. Não esqueça de adicionar os .JARS do MySql e do XStream (apenas xstream-1.3.1.jar). Abaixo temos o nosso banco vazio, aguardando os dados do XML.

Vamos usar annotations para o mapeamento do nosso bean com o Hibernate, se tiver dúvidas de como fazer isso, terá que ver alguns posts meus mais antigos de Hibernate com annotations.

A seguir temos a imagem de como vai ficar nosso projeto. Você já pode ir adicionando as classes e as bibliotecas, ao decorrer do post, vamos apresentando os códigos relevantes.

Antes de mais nada faça o download do nosso arquivo XML que possui os dados dos usuarios que vamos popular, e adicione ele à raiz do projeto. Para fazer isso basta clicar com o botão direito no projeto, escolher importar ==> File System e buscar pelo arquivo XML no seu computador.

Baixar o usuarios.xml

note: no arquivo usuarios.xml não temos o campo id para representar a coluna no banco, uma vez que este será gerado de forma automatica. Então ao abrir o arquivo sentirá falta dele.

Resolvi colocar poucos dados no XML, mas se funcionar com 2-3, deve está ok com 10,20 etc. (teoricamente sim).


Na imagem acima temos o projeto atualizado com o arquivo xml.

Pronto. Acho que até aqui estamos ok. Na próxima etapa serão os codes das classes que vamos precisar para trabalhar de verdade.

Desenvolvimento

Primeiramente você deve criar o Bean, ou seja, a classe Usuario e fazer as devidas anotações, conforme o code abaixo. Removi os getters/setters, para poupar espaço:

@Entity

@Table

public class Usuario {

@Id

@GeneratedValue

private int id;

@Column

private String nome;

@Column

private String email;

@Column

private String senha;

@Column

private String tipo;

 

Agora, configure o seu arquivo hibernate-cfg.xml com os dados de conexão do seu banco. Não esqueça de definir o mapping para a classe bean, veja como ficou o meu:


Agora vamos criar os metodos para persistência em nossa classe HibernateDAO, ficando assim:

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateDAO {

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

private static final SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

public Session getSession() {

Session session = threadLocal.get();

if (session == null) {

session = sessionFactory.openSession();

}

return session;

}

public void begin() {

getSession().beginTransaction();

}

public void commit() {

getSession().getTransaction().commit();

}

public void rollBack() {

getSession().getTransaction().rollback();

}

public void close() {

getSession().close();

}}

Agora vamos atualizar a classe UsuarioDAO que é a classe que solicita que a persistência aconteça.

public class UsuarioDAO extends HibernateDAO{

public void create(List<Usuario> listUser){

for (Usuario usuario : listUser) {

begin();

getSession().save(usuario);

try{

commit();

}catch (HibernateException e) {

e.printStackTrace();

rollBack();

}

}}}

Para quem já trabalha com Hibernate nada de especial até aqui. Lembrando que o objetivo do post não é explicar Hibernate e sim, mostrar como popular dados de um XML no banco.Então não vou entrar em detalhe sobre o code acima, qualquer dúvida basta consultar outros posts meus que explico em detalhe o Hibernate.

Vamos atualizar a classe LerDadosXML, que como nome já diz, ela será responsável

public class LerDadosXML {

private List<Usuario> listUsuario;

public List<Usuario> lerXml(Reader fonte){

XStream stream = new XStream(new DomDriver());

stream.alias(“Usuario”, Usuario.class);

List<Usuario> fromXML = (List<Usuario>) stream.fromXML(fonte);

popularData(fromXML);

return fromXML;

}

public void popularData(List<Usuario> listUsuario){

new UsuarioDAO().create(listUsuario);

}

}

Bom, a única novidade que temos ai é o uso da API XStream que será responsável por ler os dados do XML. Para ler os dados, como pode ver é bem simples, basta chamar xStream.fromXML(fonteOrigem); no nosso caso o local onde está o arquivo XML deverá ser passado para o argumento do método, mas poderiamos definir isso na mão grande algo como readerFile = new FileReader(new File(“nomedoarquivo.xml”));

Testando

Para testar e ver se de fato que planejamos vai acontecer, farei um unit test. Se não quiser usar unit test, pode criar a classe com o método main e executar.

A seguir temos o test passando e o banco populado:

public class LerDadosXMLTest {

@Test

public void testLerDadosXMLEPopulaNoBanco() throws FileNotFoundException{

FileReader fileReader = new FileReader(new File(“usuarios.xml”));

LerDadosXML lerDadosXML = new LerDadosXML();

assertFalse(lerDadosXML.lerXml(fileReader).isEmpty());}

}



 

Bom vou ficando por aqui, espero que tenham gostado do post.

Abracos, see ya!!

Resolvendo Data Truncation Hibernate


olá Pessoal,

O post de hoje vou falar de uma exceção que pode acontecer durante sua vida de programador. É o famoso data truncation. Se você nunca passou por ela as chances são grandes. Sabemos que é uma pratica muito comum de devs atuar como DBA, analisa de requisito, devesenvolvedor etc. Isso varia do projeto e política da empresa. Eu tenho uma opinião sobre essa pratica e até onde ela ajuda e atrapalhada no dia-dia. Mas daria um post, então não entrarei em detalhes.

lets go…

java.sql.dataTruncation hibernate could not insert

Essa exceção ela pode aparecer do nada, você pode chegar no dia seguinte e ter um bug aberto para ser corrigido com essa exceção. Respire e não se assuste. Mas, o que mudou de ontem para hoje? Pois, até ontem aplicação rodava tão bem, que não recusei o convite de um happy-hour.

O que aconteceu?

O que aconteceu é que o cara que cuida do Banco de dados, simplesmente mudou o tamanho de uma coluna(de 100 para 50) e quando o usuario foi inserir um novo dado maior que 50 para a coluna X, daí já era. Temos dados demais para aquela determinada coluna.

Solução

– Há varias soluções uma delas, é você já limitar o formulario para o tamanho X e validar esse tamanho antes de enviar os dados para o banco.

– se você está pegando dado de outro banco, se puder veja o data model e deixe sua coluna igual dos dados de origem.

Um detalhe importante é que esse tipo de dado não deveria mudar a fim de gerar um data truncation. Normalmente quando há alterações na maioria das vezes é para aumentar o capacidade, porém já passei pelo inverso também e foi data truncation na certa.

Então se você estiver passando por esse e-mail valide o tamanho dos dados que vai ser inserido no banco e veja com o responsável pelo banco como está o tamanho da coluna X data base.

Vou ficando por aqui, espero que tenham curtido a dica.

See ya!!! abraços,

1 ano Guia do Exame SCJP

 

Olá pessoal,

O post de hoje é um pouco diferente. O tempo passa muito rápido ou eu estou ficando velho rs. Mas, na ultima sexta-feira meu filhão, completou 1 ano de vida (alguem aqui lembra desse post?).

Que felicidade, para o paizão aqui, pois ele superou as expectativas, não pela vendas, pois vender não é díficil, basta ter um bom departamento de MKT. Mas, não é o caso dele, a maioria das vendas foram por indicações, outros por já conhecer o blog e arriscou em comprar um trabalho meu hehe. E o melhor é que meu filhão fez, foi fazer os leitores darem feedback seja via twitter ou por e-mail, mas os leitores queriam dar um retorno, se sentiam empolgados e compartilhavam o que de fato estavam achando do livro. Não é uma tarefa fácil obter um feedback quando é positivo, é lei do ser humano, querer sempre comentar quando é algo ruim, e ai ele que descarregar toda energia, postando as críticas etc. O desafio é conseguir o inverso, extrair do leitor o que de fato ele achou e o “Guia do exame SCJP” conseguiu motivar os leitores a dar um grito de guerra :).

Quero agradecer à todos os leitores, que enviaram sugestões, elogios, criticas aqui no blog, e-mail, twitter etc. Fico muito grato.

Para os curiosos, em saber o nro de vendas, o que posso dizer por questão de contrato, é que dos 1 mil exemplares disponíveis em 1 ano já vendemos mais que 50% e não falta muito para terminamos com o estoque. De fato não esperava isso em 1 ano, uma vez que há livros que levam 2 anos ou mais para atingir os 1 mil. Sem falar que é um hábito de nos brasileiros que antes de comprar uma obra brasileira, primeiro buscar uma de origem “made in english”. Mas, podemos ver mudanças acontecendo neste cenário.

Não posso deixar de agraceder ao Padrinho do meu filhão, o meu amigo de longas datas o Edson Gonçalves, se não fosse o Gonçalves, nem teria pensando em escrever a “dedicatoria” do livro.


Abraços à todos!!!

see ya!!

Criando JAR com MySQL,Hibernate e Quartz

olá pessoal,

O post de hoje é algo bem iniciante, mas ainda muito usado quando estamos trabalhando com protipo de algo e precisamos apenas validar se uma solução vai funcionar de fato. Ou seja, quando estamos na ponta do iceberg. Então hoje, vou mostrar como criar um arquivo JAR pelo Eclipse, mas não será um arquivo JAR qualquer com um “Hello World” apenas, este terá que connectar à um banco de dados MySQL e ainda o Quartz. Então somente neste contexto temo três APIs externas no aplicativo, pois o Hibernate fará o terceiro.

Lets go…

Alguns requisitos:

  • ter o hibernate configurado, dúvidas consulte outros posts do Hibernate aqui.
  • ter todas as libs no projeto
  • antes de criar o JAR, certifique-se que tudo funciona no modo de DEV(hibernate, conexão com banco etc. Rode e check os resultados inúmeras vezes;
  • tenha o MySQL 5/superior instalado;

Starting…

Vamos dizer que você precise mostrar a funcionalidade de algo da maneira mais simples possível, e quem for ver está mais preocupado na funcionalidade do que em layout, performance (por enquanto). Como trabalho com pesquisa e desenvolvimento tenho passado por isso com bastante frequência, uma vez que no inicio de algo estamos no prototipo para uma possível nova feature, solução, seja o que for, mas não é legal no inicio gastar muita energia, com performance, layout, ou qualquer caracteristica que não agrega valor na funcionalidade. Caso a ideia não seja válida, o resultado será que gastei menos energia e tempo. E já foi possível descartar.

Situação

Um dia desses tive que apresentar uma solução para uma feature do projeto que, nem sabiamos se ia dar certo e como seria os impactos. Daí começamos com as investigações e pesquisa necessária, e quando fomos apresentar para os arquitetos, o team de Q.A etc. Foi algo bem produtivo porque geramos um JAR com o banco HSQLDB, distribuimos esse JAR e eles só executaram e viram o resultado desejado (não posso dar maiores detalhes). Já pensou se fosse necessário ter que montar todo o ambiente de DEV na maquina de quem fosse validar a solução? Exemplo: de ter que instalar um banco real, configurar os acessos etc. Bem, nada produtivo né?

HSQLDB: é um banco em Java que não passa de JAR e que por sinal é bem completinho, porém com suas limitações e não queira comparar ele com MySQL, SQL Server, Oracle etc . Basta adicionar o .jar ao seu projeto e terá o HSQLDB disponível para receber os dados. Claro que terá que informar ao hibernate.cfg.xml sobre isso. Qualquer dúvida, basta dar uma “googlada” que encontrará vários posts a respeito de como usar o HSQLDB. A documentação também ajuda: http://hsqldb.org/ http://pt.wikipedia.org/wiki/HSQLDB

 

Note

Aqui vamos usar o MySQL 5 então vou levar em conta que você já tem ele instalado na sua maquina. Também, acredito que já tem o projeto do ultimo post rodando. Mas, caso não tenha use qualquer outro projeto pessoal que tenha acesso à um banco de dados, que use o hibernate, para ficar bem próximo do nosso.

Development

Eu poderia ter ido direto ao ponto e ter feito o post com 3,4,5 linhas, mas sempre gosto de fazer um contexto, para quem está lendo possa ter uma ideia da utilização, principalmente se está vendo o assunto pela primeira vez, é mais importante ainda, pois saber o porque das coisas é tão importante quando saber fazer. Não saia fazendo, por fazer. Sempre se pergunte o por que fazer isso?

  • uma vez com o projeto criado no eclipse, clique com o botão direito e escolha build path → configure build path.
  • agora precisamos informar as libs que serão exportadas

observe que marquei as bibliotecas que preciso. No caso do nosso exemplo são: hibernate, quartz e mysql.

  1. Clique em ok
  2. agora clique com o botão direito no projeto e escolha export
  3. procure pela pasta Java
  4. e escolha Runnable JAR e clique em next

  1. agora precisamos informar o projeto, que no caso será QuartzDBHibernate

  1. indique o local que deseja salvar seu arquivo JAR.
  2. Clique em finish e aguarde terminar (talvez apareça um warning, se quiser clique em details leia e prossiga. Não é nada critico)

Uma vez com JAR gerado, vamos testar a execução. No caso do windows abra o promt de comando e navegue até onde salvou o seu JAR. E digite: java -jar quartzdbHibernate.jar (eu usei o mesmo nome do projeto, você deve informar o nome que deu ao arquivo JAR caso tenha sido diferente).

 

Agora vamos ver o resultado, ahh não esqueça de dar um START no seu MySql do contrário verá exceções na tela.

Observe que foi adicionado o usuario, o sql é printed  pelo hibernate uma vez que configurei no hibernate.cfg.xml para ser impresso. Agora vamos  ao  banco.

Na imagem acima temos o banco atual e veja que o ultimo ID é 60. na imagem a seguir temos o banco atualizado e o ultimo ID é 61:

 

Alguns profissionais “Senior”  crucificaria o Camilo por fazer um post deste tipo, tão ABC.  Mas, como sempre falei : “todo sênior hoje um dia deu hello world, e passou pelas mesmas dificuldades que alguem que está chegando hoje no mundo java está passando, e com certeza  esse senior precisou de ajuda, e pq ignorar de dar essa ajuda hj ?”. O que tenho aprendido nesses 3 anos como blogueiro  foi o seguinte: o mais prazeroso  não é escrever um post “avançadao ou basicao” para querer mostrar que “sabe” algo. E sim saber, o que foi escrito teve um impacto positivo na vida do leitor  independente do nível do post. Até hoje  lembro das noites em claro que passei, para instalar e configurar o Java corretamente no windows, e a dificuldade que tive em fazer isso de forma automatica, sem precisar “googlar” fazer aquele javac funcionar era osso. E quando conseguir, virou meu primeiro post do blog, e foi onde tudo começou. E até tenhoo leitores comentando que o post tem salvado o dia deles.

Vou ficando por aqui e espero que tenham gostado do post.

abracos see you next post!!!

Usando quartz com o Hibernate

opa! Pessoal,

O post de hoje vou apresentar API Quartz. O objetivo é mostrar como Quartz é simples de usar. E para contexto, escolhi que criaremos um job, que terá como trabalho de popular um banco a cada X time, que nesse caso vamos usar o Hibernate para fazer esse tramapo. O Quartz nada mais é que um scheduler de jobs, que podem ser executados em momento determinados. No decorrer do post veremos mais na prática.

Lets go…

Para usar o quartz basta fazer download do jars(quartz-all.x.jar) e adicionar ao projeto. Adicione as libs do Hibernate e Banco de dados (aqui usaremos o MySQL) ao projeto também.

API QUARTZ: http://www.quartz-scheduler.org/

*Caso tenha dúvida sobre o Hibernate, veja os nossos posts na categoria.

Desenvolvimento

Para usar quartz vamos criar um package br.com.camilolopes.scheduler neste packages teremos uma classe responsavel por executar os jobs programados.

No package br.com.camilolopes.job é onde temos a classe que tem um trabalho a ser feito, que no nosso caso é persistir no banco de dados.

Package br.com.camilolopes.dao tem as configurações para o Hibernate que não está atrelado ao quartz.

Primeiro passo

É começar com a classe SchedulerJobs no package br.com.camilolopes.scheduler onde vamos definir os jobs a serem executados e o time para eles. Como esta classe será a principal, ela terá o método main.

 

package br.com.camilolopes.scheduler;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import br.com.camilolopes.job.PersistDB;

/*
* esse é o agendador de jobs
*/
public class SchedulerJobs {

public SchedulerJobs() {
// TODO Auto-generated constructor stub
}
public static void main(String[]args) {

//neste caso a cada 1 min
Trigger trigger = TriggerUtils.makeSecondlyTrigger(30);
trigger.setName(“jobdb”);
/*dou informacoes qual classe ele deve chamar
ou seja, o trabalho a ser feito
*/
JobDetail jobDetail = new JobDetail(“save db”, PersistDB.class);
try{
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
//info o job a ser feito e de em qto em qto tempo passando o trigger
scheduler.scheduleJob(jobDetail, trigger);
//peco para iniciar
scheduler.start();
}catch (SchedulerException e) {
e.printStackTrace();
}

}
}

Trigger = esta classe é responsável por configurar o tempo em que cada job será executado, nesse caso configuramos para a cada 30s. Veja que usamos a classe TriggerUtils. Que já possui alguns metodos implementados e não vamos precisar reiveitar a roda. Em seguida damos um nome para esse trigger.

JobDetail = é aqui que temos o job a ser executado nesse caso mandamos executar o job que está na classe PersistDB.class, veja que damos um nome para esse nome.

Scheduler = aqui onde temos uma instancia de um scheduler que será responsavel por executar o job, e como criamos uma instancia de uma factory, precisamos apenas informar o job e o tempo que ele vai ser executado nesse caso, é vai a variavel de JobDetail e o time que definimos em Trigger. Para iniciar o job chamamos o metodo start().

Na classe a serguir temos o trabalho a ser feito que é criar um usuario e chamar o método save() responsável por fazer o trabalho de persistência no banco de dados.

public class PersistDB implements Job{

@Override

publicvoid execute(JobExecutionContext arg0) throws JobExecutionException {

UsuarioQuartzDao usuariodao = new UsuarioQuartzDao();

Usuario usuario = new Usuario();

usuario.setEmail(“camilo@”);

usuario.setNome(“lopesff”);

usuario.setSenha(“123”);

usuario.setTipo(“admin”);

usuariodao.save(usuario);

System.out.println(new Date());

}

}

A classe que possui o job a ser feito precisa implementar a interface Job e colocar o trabalho dentro do metodo execute().

Classe DAO.

public class UsuarioQuartzDao extends DAO {

public void save(Usuario us){

begin();

getSession().save(us);

try{

commit();

}catch (Exception e) {

e.printStackTrace();

}}

}

Na classe acima é onde ocorre a persistencia com o banco usando o Hibernate, um detalhe que quero chamar atencao é pedi para o Hibernate criar a table e a cada vez que o job rodar ele não criar uma nova table e sim adicionar apenas os dados, para isso seu arquibo hibernate.cfg.xml deve ter um update no hb2mddl.auto como update, se não existir ele cria de forma automatica.

<property name=“hibernate.hbm2ddl.auto”>update</property>

O code completo:

<property name=“hibernate.connection.driver_class”>org.gjt.mm.mysql.Driver</property>

<property name=“hibernate.connection.password”>blog</property>

<property name=“hibernate.connection.url”>jdbc:mysql://localhost/blogleitores</property>

<property name=“hibernate.connection.username”>camilolopes</property>

<property name=“hibernate.dialect”>org.hibernate.dialect.MySQL5InnoDBDialect</property>

<property name=“hibernate.show_sql”>true</property>

<property name=“hibernate.current_session_context_class”>thread</property>

<property name=“hibernate.transaction.factory_class”>org.hibernate.transaction.JDBCTransactionFactory</property>

<property name=“hibernate.hbm2ddl.auto”>update</property>

<mapping class=“br.com.camilolopes.bean.Usuario”/>

 

Resultado

Ao executar o code, temos os resultado conforme a seguir:

 

 

Observe que o Job é executado dentro do tempo e o trabalho de persistir de fato acontece. Um fato que identifiquei é que se o job, demorar mais que o tempo configurável o próximo job, tem que aguardar o outro finalizar para iniciar o trabalho dele. Outro ponto se configurarmos o método shutdown (true) e colocar depois do método estar, assim após o termino de todos os jobs, o scheduler é “desligado” e os trabalhos não mais reiniciados. No nosso exemplo ele roda de maneira infinita.

scheduler.start();

scheduler.shutdown(true);

Vou ficando por aqui e espero que tenham gostado do post, eu tenho usado o quartz em algumas soluções no meu job e de fato é uma API excelente. Além de uma boa documentação, o fórum é bem ativo para tirar duvidas.

Abraços, see you next post. 😀