Caelum | Ensino e Inovação - Cursos de Java, Scrum, Ruby on Rails


As dependências do Hibernate 3.5

Por Paulo Silveira em 14/04/10

O primeiro desafio de um iniciante em Hibernate, antes mesmo de fazer um tutorial prático, como o disponível na apostila FJ-21 da Caelum, é organizar as dependências necessárias. Até o Hibernate 3.3, a maneira a qual ele era distribuído dava trabalho pra quem precisasse usar a JPA: além do zip contendo o hibernate, era necessário fazer o download de um outro jar contendo a implementação do EntityManager e ainda outro contendo as anotações e interfaces da JPA.

A versão 3.5, além de trazer uma implementação da JPA2, juntou todos esses pacotes em um só. A documentação está ainda mais completa, assim como a parte explicando o processo de setup do seu primeiro projeto. Apesar disso, como se pode ler na documentação, ela é feita assumindo que você esteja usando o maven. Muitos iniciantes em Java ainda tem dificuldades pra encarar o Maven, ou há ainda quem prefira usar o Ant, Ivy ou gerenciar as dependências manualmente. Quais dependências preciso então para rodar uma aplicação com Hibernate 3.5?

Para facilitar seu trabalho, deixamos aqui um zip com todas essas dependências do Hibernate 3.5.0, além de um arquivo de configuração para o Log4J, um hibernate.cfg.xml e jars opcionais.

Ou então você pode juntar esses jars seguindo o passo a passo: primeiramente precisa baixar a distribuição 3.5 a partir da página de downloads do hibernate no sourceforge. Ao descompactá-la, encontramos os seguintes arquivos e diretórios:

O hibernate3.jar é um jar contendo as classes fundamentais do Hibernate. Agora, dentro de lib, temos o diretório required, que são dependências que sempre precisaremos utilizar junto com o Hibernate. Todas essas 6 dependências são necessárias:

Dentro de lib, ainda precisamos do jar hibernate-jpa-2.0-api-1.0.0.Final.jar que está na pasta jpa para poder utilizar as anotações do Java EE. Caso você va usar o MySQL, também precisa fazer o download do driver JDBC para ele.

Ainda não terminou. Precisamos do nosso logging funcionando. Se você tentar executar algum exemplo agora, vai receber o conhecido Exception in thread “main” java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder. O SL4J, usado pelo Hibernate, é uma casca para as outras ferramentas de logging, e precisa então de um jar que indique qual logger será utilizado como backend. Na página de distribuições do SL4J você deve baixar a versão correspondente que está usando, seria a 1.5.8 no caso do Hibernate 3.5.0, e pegar o adaptador slf4j-log4j12-1.5.8.jar. Também precisamos do jar do Log4J 1.2.x.

Principais dependências opcionais

Usar o Hibernate facilita muito o desenvolvimento com banco de dados, porém para uma performance e escalabilidade adequada é necessário ficar atento em alguns pontos fundamentais, e também simples, para que ele não se torne um gargalo na sua aplicação. Dentro do diretório optional, destaco como essenciais o c3p0 para pool de conexão e o ehcache para second level cache.

Para você tirar todo o poder da JPA 2, vai querer também usar a api de meta modelos, e pra isso precisa do gerador de modelos do Hibernate.

  • Share/Bookmark

Java EE 6: Começando com Bean Validation

Por Lucas Souza em 03/02/10

Não existe tarefa mais comum hoje em dia do que validar dados em uma aplicação. Por exemplo, validamos se na camada de apresentação o usuário preencheu algum campo obrigatório, depois fazemos a mesma lógica de validação em nossa regra de negócio e por último validamos se os dados que serão salvos no banco também estão corretos. O que na maioria das vezes os desenvolvedores fazem é validar estas regras em todos os lugares, e muitas vezes resulta em validações complicadas e possíveis erros na aplicação. Muitos desenvolvedores consideram essa tarefa enfadonha.

Na nova versão do Java EE lançada dezembro de 2009 existem grandes novidades: Servlets 3.0, JAX-RS, CDI, JSF 2.0 e a Bean Validation, definida pela JSR 303. Com a Bean Validation é possível realizarmos validações atráves de metadados (anotações) e as utilizarmos em todas as camadas de nossa aplicação.

Podemos até mesmo criar nossas próprias regras de validações e aplicarmos em outros pontos do nosso sistema. Essas regras podem ser facilmente integradas com JPA e JSF, por exemplo. Vamos considerar uma classe que represente um contato:


public class Contato {

  private String nome;

  private String email;

  // getters e setters

  public void enviaEmail() {
    // codigo envio de email
  }
}

E vamos adicionar nossas regras de validação utilizando a Bean Validation:


public class Contato {

  @NotEmpty
  @Pattern(regexp = ".+@.+\\.[a-z]+")
  private String email;
   
  @NotEmpty
  private String nome;

  // getters e setters

  public void enviaEmail() {
  // codigo envio de email
  }
}

A anotação @NotEmpty garante que o email não poderá ser vazio assim como o atributo nome. No atributo email também colocamos a anotação @Pattern, onde podemos passar qualquer expressão regular, que o Bean Validation validará o valor passado ao atributo nome com a expressão regular.

Lembrando que o Bean Validation é uma especificação e como toda especificação, para utilizarmos precisamos de uma implementação para a utilizarmos. A implementação usada nos exemplos é a Hibernate Validator, e é a implementação de referência.

Integrando com o JSF

O código abaixo mostra um formulário simples utilizando JSF, que chama um método enviaEmail do ManagedBean quando clicamos no botão “EnviaEmail“:

<h:form id="formulario">
     <h:panelGrid columns="3">
          <h:inputText id="email" value="#{contato.email}"/>
          <h:message for="email" styleClass="error"/>
          <h:commandButton action="#{contato.enviaEmail}"
               value="Enviar Email"/>
     </h:panelGrid>
</h:form>

Precisamos ainda anotar nossa classe Contato com @ManagedBean(name="contato") e @RequestScoped para que a mesma seja um ManageBean e consiga integrar-se com o JSF.
Quando clicarmos no botão “Enviar Email” automaticamente será validado se o atributo email foi preenchido a atende a expressão regular da anotação @Pattern.

Podemos muitas vezes nos deparar com algum caso onde é necessário fazermos uma validação um pouco mais específica, algo que não esteja implementado por padrão no Bean Validation. Validar um CEP seria um bom exemplo. O primeiro passo para fazermos nossa própria validação é criar uma anotação que sugira o nome desta validação.


@Constraint(validatedBy = CepValidator.class)
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cep {
  
  String message() default "Cep inválido";
  Class<?>[] groups() default { };
  Class<? extends Payload>[] payload() default { };

}

Reparem que em nenhum momento fizemos de fato a validação se o CEP é válido ou não. Por isso anotamos a anotação CEP que acabamos de criar com @Constraint e setamos o atributo validatedBy com a classe que está nossa validação realmente.
O próximo passo é criarmos a classe CEPValidator que fará a validação. Esta classe tem que obrigatóriamente implementar a interface javax.validation.ConstraintValidator:


public class CepValidator implements 
            ConstraintValidator<Cep, String> {

  private Pattern pattern = 
          Pattern.compile("[0-9]{5}-[0-9]{3}");

  @Override
  public void initialize(Cep constraintAnnotation) {

  }

  @Override
  public boolean isValid(String value, 
           ConstraintValidatorContext context) {
    Matcher m = pattern.matcher(value);
    return m.matches();
  }

}

No método isValid verificamos e retornamos um booleano dizendo se a String passada como argumento está de acordo com a expressão regular que criamos no topo da classe. Podemos agora validar qualquer atributo de algum Java Bean, devendo apenas anotar o atributo com a nossa recém criada @CEP. Por exemplo:


public class Contato {

  @Cep
  private String cep;

  // getters e setters
}

Para rodar esse exemplo precisamos de um servidor de aplicação compatível com o Java EE 6, como o Glassfish 3.0. A premissa do Bean Validation é que muitos outros frameworks acabem por adotar um único mecanismo de validação, sendo possível reaproveitar o código criado aqui. O Caelum Stella, que fornece diversos validadores para sistemas que envolvem o domínio brasileiro, em breve será compatível com essa especificação, possibilitando que você utilize-o em todas as diversas especificações que compões o Java EE.

Além disso precisamos de um Servidor de Aplicação compatível com a versão 6 do Java EE. Por enquanto o único servidor que implementa essa versão é o Glassfish v3.0 que por sinal também é uma implementação de referência.

  • Share/Bookmark

Nova versão da Apostila FJ-28 liberada com VRaptor 3.1

Por Lucas Cavalcanti em 13/01/10

Depois de mais de 4000 downloads nesses 3 meses de vida, lançamos o VRaptor 3.1 com muitas novidades e bugfixes, com destaque ao suporte aos novos recursos das servlets no Java EE 6, o que permite usar o VRaptor 3 sem nem mesmo um web.xml em containers compatíveis com servlets 3.0, além de novos recursos para AJAX, lógicas genéricas e facilidades no mapeamento de URLs, forwards e redirects.

vraptor apostila

Aproveitando o lançamento dessa nova versão do framework, estamos disponibilizando a atualização da apostila do curso FJ-28 de VRaptor, Hibernate e AJAX, que já está disponível para download. O material não abrange apenas VRaptor, Hibernate e JSP, mas também entra em detalhes de como fazer a costura de maneira correta, gerenciando suas Sessions, Transactions, etc, através da criação de uma webapplication desde o zero.

  • Share/Bookmark

Livro Arquitetura e Design de Software: mais 4 tópicos liberados!

Por Sérgio Lopes em 04/11/09

arquitetura e design de softwareHá três meses anunciamos o livro Arquitetura e Design Java, um livro que está em seu processo de finalização, fortemente baseado na experiência da Caelum com debates no curso de Arquitetura e Design, a adminstração do GUJ.com.br e esses anos de consultoria.

Os 4 tópicos liberados agora são “Java como plataforma não como linguagem”, “Favoreça imutabilidade e simplicidade”, “Cuidado com o modelo anêmico” e “Considere uma ferramenta de mapeamento objeto relacional”. Eles se juntam aos outros 4 tópicos liberados anteriormente (“Gerenciar memória não é simples”, “Programe voltado a interface, não a implementação”, “Entendendo o NoSuchMethodError e o ClassLoader hell” e “Inversão de Controle: Cadê a minha chave de fenda?”). Confira no site!

Além disso, atualizamos os tópicos do livro com novos temas que estamos finalizando, como REST, Cloud computing, bancos de dados não relacionais, modelos anêmicos e outros.

Este é um livro que aborda desde código até a arquitetura numa visão mais ampla. Como Craig Larman já afirmou: Você deve enfrentar suas batalhas, sejam elas no nível macro-arquitetural ou no humilde campo das instâncias“. Essa distinção, sobre o que é design e o que é arquitetura, não fica muito clara dentro do livro, pois muitas vezes é até difícil separar nessa classificação. Martin Fowler fala o mesmo no âmbito de patterns logo na segunda página de seu livro Patterns of Enterprise Application Architecture: “Alguns dos padrões nesse livro podem ser chamados arquiteturais, já que representam decisões importantes sobre essas partes; outros são mais sobre design e te ajudam a implementar essa arquitetura. Eu não faço nenhuma tentativa forte de separar esses dois, já que é o que é arquitetural ou não é subjetivo.”.

Estamos em processo de finalização do livro e gostaríamos muito de receber feedbacks e opiniões!

  • Share/Bookmark

A java.net.SocketException Broken Pipe

Por Paulo Silveira em 19/10/09

Quando começamos a programar com banco de dados, rapidamente aprendemos que devemos sempre usar um pool de conexões para acessa-lo, caso contrário podemos facilmente atrapalhar o bom funcionamento do mesmo, devido o excesso de conexões.

Passamos então a usar um pool de conexões, e ao colocar o sistema em produção, nos deparamos com outro problema: o broken pipe:

java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2690)
...

No GUJ, são mais de 100 mensagens a respeito de broken pipes! Recentemente Tomaz Lavieri abriu um detalhado tópico sobre esse mesmo assunto, que me incentivou a escrever esse post, dada sua relevância.

Por que essa exception acontece? São dois motivos principais:

O primeiro é que muitos bancos de dados possuem um timeout para conexões inativas (o padrão do MySQL é de 8 horas, mas em alguns hosts isso pode estar configurado em segundos!). Depois de determinado tempo, o banco de dados mata essa conexão ociosa numa tentativa de economizar recursos, pois conclui que alguém simplesmente a esqueceu aberta. Quando, no lado do cliente, seu pool decide usá-la, a socket rapidamente percebe que a conexão foi fechada do outro lado, foi quebrada (daí o nome broken pipe). Muito comum ao começar a usar um pool!

O segundo motivo é que você pode estar tratando suas transações sem o devido cuidado: esquecendo de fazer o commit ou o rollback em alguns casos. O banco de dados então pode matar essa conexão depois de algum timeout de transação, porém o seu pool não sabe disso, e quando for utilizar essa conexão, ela está quebrada!

Solução rápida? Configurar o seu pool para testar se as conexões continuam válidas. No C3P0, pool de conexões que recomendamos fortemente, quando usado com o Hibernate, basta fazer no seu hibernate.cfg.xml:

<property name="hibernate.connection.provider_class">
  org.hibernate.connection.C3P0ConnectionProvider
</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.timeout">30</property>
<property name="hibernate.c3p0.idle_test_period">100</property>

É a configuração hibernate.c3p0.idle_test_period que resolve o broken pipe. Nesse caso o C3P0 fara essa verificação de maneira assíncrona: ele cria threads (3 por padrão) que checam de tanto em tanto tempo (100 segundos nesse caso) se alguma das conexões do pool está inválida (broken pipe é um dos casos). Na existência de uma conexão assim, essa será eliminada do seu pool! Você ainda pode ter um azar muito grande, pois uma conexão pode ter algum problema logo depois que a thread a verificou! Se você quer ter uma confiabilidade de 100% em relação a suas conexões, você pode configurar a variável testConnectionOnCheckout no arquivo c3p0.properties que deve ser colocado no seu classpath. Isso não é muito recomendado, pois toda vez que uma conexão é pega do pool, alguma forma de ping será feito no banco de dados para saber se ela é válida, perdendo um pouco de performance.

Vale lembrar de que isso não é motivo para você se descuidar no tratamento de transações, centralizando isso dentro de um interceptador/filtro que faça o uso correto do try, catch e finally, precavendo-se de qualquer vazamento. Transações, assim como qualquer outro recurso caro (arquivos, conexões, sockets, threads, etc…), deve ter seu ciclo de vida tratado com atenção, de preferência de maneira isolada.

Caso você não use Hibernate, Jerônimo Mozer mostra como usar o C3P0 programaticamente.

Mais detalhes podem ser vistos nas configurações de teste de conexões do C3P0, detalhes do seu funcionamento com o Hibernate e a página do próprio Hibernate sobre esse pool, mas que se encontra um pouco defasada. Também vemos muitos detalhes como esses no capítulo de dia a dia com Hibernate do nosso curso FJ-26.

  • Share/Bookmark



Caelum | Ensino e Inovação
São Paulo: Rua Vergueiro, 3185, cj. 87, próximo ao Metrô Vila Mariana   |   Tel. (11) 5571-2751
Rio de Janeiro: Rua Senador Dantas, 80, cj. 307/308 - Centro   |   Tel. (21) 2220-4156 ou 2297-0033
Brasília: SCS Qd. 8 Bl. B-50, Sala 521 - Ed. Venâncio 2000   |   Tel. (61) 3039-4222