Resolvendo LazyInitializationException em 5 minutos

Olá Pessoal,

No post de hoje vamos ver como podemos resolver o LazyInitializationException em 5 minutos. Dificilmente um desenvolvedor não passou por essa exceção. Não vou entrar em detalhes sobre o motivo  da exceção LazyInitializationException, até por que já falei em um post aqui no blog, usando a solução com filter.

Lets go…

Na prática

Para mostrar a solução na prática, vou pegar um exemplo simples. Vamos considerar o relacionamento de que um Type  tem muitos Users, veja

@Entity

@Table(name = “type”)

public class Type implements java.io.Serializable { 

private static final long serialVersionUID = 2644022136811709451L; 

private Long id;

private String description;

private Set<User> users = new HashSet<User>(); 

public Type() {

}

@Id

@GeneratedValue

@Column(name = “ID”, unique = true, nullable = false)

public Long getId() {

return this.id;

}

@OneToMany(fetch = FetchType.LAZY, mappedBy = “type”,  targetEntity=User.class)

public Set<User> getUsers() {

return this.users;

}

//getters/setters omitidos

}

User.java

@Entity

@Table(name = “user”, uniqueConstraints = @UniqueConstraint(columnNames = “EMAIL”))

public class User implements java.io.Serializable,Comparable<User> { 

private static final long serialVersionUID = 9108778602728711429L; 

//declaração de variaveis omitidas 

@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = “TYPE_ID”,nullable=false)

public Type getType() {

return this.type;

}

//getters/setters omitidos

} 

Nada de especial até aqui, apenas o relacionamento que já conhecemos.

O problema

Agora que temos o problema, quando o User.java tentar acessar o Type e a conexão já foi fechada, já sabemos que vamos resolver LazyInitializationException. Uma forma para resolver é usando  join fetch, que evitará o problema pelo seguinte motivo:

– Apenas uma consulta será feita e evitamos o problema N + 1;

– A realização da consulta vai deixar de ser Lazy para Eager. Isso é diferente de você mudar de Lazy para Eager.

No DAO

Devemos ter a consulta assim:

public class UserDAO{

public List<User> readAll() {

                //avoiding LazyInitializationException join fetch

                String hql = “select u from User u join fetch u.type”;

                Query query = getCurrentSession().createQuery(hql);

                return query.list();

        }

}

Pronto. Resolvido seu problema com LazyInitializationException. Mas um detalhe importante é que para cada coleção que temos, é uma consulta que devemos ter. Se Type tem uma coleção de acesso, é uma consulta.

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

Abraços, see ya!! 

Série CI: Integrando Sonar com Jenkins

Olá Pessoal

No post de hoje veremos como integrar o sonar com o jenkins.  Para quem não sabe, o sonar é uma ferramenta PMD para análise do código. Em outras palavras, o Sonar olha e diz: “o nome dessa variável não está legal”, “ei tem código duplicado nessa classe”, etc. Vamos ver  como integrar essa ferramenta com o build, pois logo após fim do build o sonar roda e faz o trabalho dele.

Lets go..

Primeiro Passo

Baixe o sonar http://www.sonarqube.org/downloads/ . Para o exemplo estou usando o sonar 3.4.1, pois é o que tenho aqui . E a versão SonarQube.

Segundo Passo

Vou considerar que você já vem acompanhando a série Continous Integrations com Jenkins aqui no blog, então você já tem o Jenkins e um projeto configurado.

Terceiro Passo

Após ter baixado o sonar, descompacte o .zip e via prompt de comando vá até

sonar-3.4.1\bin

Em seguida entre na pasta referente ao sistema operacional que está usando e execute o arquivo .bat ou .sh.

 

sonarrunninglocal

 

sonarrunning

Quarto Passo

Inicie o Jenkins

Quinto Passo

Instale o plugin do sonar no Jenkins sem reiniciar aplicação. 

 

sonarjenkinsplugin

Sexto Passo

Após  instalação vá em Jenkins >> Manage Jenkins >> Configure Systems . Você vai ver que o sonar foi adicionado. Clique em advanced e deixe conforme a  seguir:

 

sonarconfigjenkins

Apenas informamos a URL onde o Sonar está sendo executado, o resto deixamos em branco porque estamos rodando local e com o banco embedded.  Para fazer com um banco real, consulte a documentação do sonar.

Clique em save.

Sétimo Passo

Vá em configure do seu  projeto no Jenkins

sonarprojectconfigure

E em post build actions clique em add e escolha sonar:

Ao clicar em Add post-build action escolha a opção “Build Pipeline Plugin >> Manually Execute Downstream Project”

 

sonarbuildpost

E deixe assim:

 

sonarjob

Save.

Oitavo Passo

Build Now o projeto e aguarde:

 

sonarbulding

 

sonarbuilddone

 

sonarappreaderweb

Pronto! Simples, não?

Vou ficando por aqui. Espero que tenham gostado.

See ya!!

Abraços.

Série CI:Resolvendo problemas de Unicode maven no Jenkins

Olá Pessoal,

O post de hoje é bem rápido, mas muito recorrente quando estamos montando um ambiente continuo. No meu caso tive problemas de Unicode quando o jenkins executou mvn test. Vamos ver como resolver.

Lets go… 

O problema

A questão é que os testes vão falhar. Se você tem algum teste que faz validação que envolve acento, por exemplo  você espera “João”  e devido ao problema de Unicode veio sem o acento e outro caractere. Como resolver?

 

readerwebbuildfailuretestes

A solução

É bem simples, precisamos apenas no nosso pom.xml informar qual Unicode vamos usar, nesse caso UTF-8. Daí precisamos configurar as propriedades assim:

<properties>

<maven.test.failure.ignore>false</maven.test.failure.ignore> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

   <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

</properties>

 E agora podemos executar um mvn clean. E em seguida mandar o Jenkins compilar e o resultado será:

readerwebbuildsucessunicode

Pronto, problema resolvido. Simples não?

Abraços, see ya!!!

Overview I4JSF API for JSF Internationalization

Olá Pessoal,

O post de hoje é um pouco diferente. O objetivo é apresentar para vocês o I4JSF API. Ué, mas que API é essa, Camilo? É uma API para JSF com o objetivo de ajudar a evitar a repetição de código para internacionalização. Sim, mas por que usar essa API? Qual o ganho?

 Vamos conhecer a seguir.

Lets go…

O contexto

Antes de apresentar a API vamos entender alguns contextos que já passei e foi de onde veio a ideia de criar I4JSF API que ainda está “verde” e na sua primeira versão. Quando trabalhamos apenas com 1 projeto JSF é comum em alguns casos criar uma classe utilitária para o código de internacionalização, ou melhor, o trecho de código que trata em adicionar uma mensagem no contexto do JSF, independente se veio de um bundle  ou  uma String direta.  Nada de errado aqui. Mas e quando na empresa que você trabalha há mais de um projeto JSF? E que em algum momento há algo em comum referente à implementação entre eles?

Por exemplo, identifiquei que em 2 projetos JSF ambos tinham uma classe para tratar de maneira mais produtiva sem perder a qualidade, com código utilitário, que era criando uma classe utilitária. Daí pensei “se existe uma API em comum, não seria melhor para os dois projetos, desde a melhoria até a manutenção desse código semelhante? Quanto os desenvolvedores gastaram para criar a classe utilitária que normalmente era um código necessário, mas que não estava associado às regras de negocio do projeto, porém era preciso escrever para facilitar o trabalho?”.

I4JSF

Assim nasceu I4JSF API, com o objetivo de evitar esse retrabalho em equipes que usam JSF e vão precisar internacionalizar aplicação e não querem fazer uma classe utilitária para cada projeto JSF.  No GitHub da API você pode encontrar todas as informações de como usar, adicionar ao seu pom.xml ou fazer o download do .jar e ainda há um projeto demo I4JSFDemo, que é um JEE Project que mostra I4JSF in Action.

Claro que há muito trabalho para ser feito e adicionando API, afinal de contas ela acabou de nascer e ai temos uma oportunidade caso deseje contribuir para o desenvolvimento. Veja como:

  1. Faça um fork do projeto no Github;
  2. Implemente a melhoria;
  3. Envie sua mudança;

Um exemplo de uso. Veja a comparação de código usando I4JSF com o código natural do JSF:  

Natural JSF

FacesContext facesContext = FacesContext.getCurrentInstance();

    ResourceBundle bundle = facesContext.getApplication().getResourceBundle(facesContext, “language”);

    String byndleKey = “msg.error”;

    String msgBundle = bundle.getString(bundleKey);

    addFacesMessage(facesContext, msgBundle);

 I4JSF

new I4JSF().addTranslateContext("language", "msg.error");

FAQ

Se for preciso adicionar uma mensagem no contexto JSF via bundle, como faço?

– Simples, chame o método public void addTranslateContext(String bundleVar, String keyProperties) e passe o nome da variável bundle declarada  e a key do bundle e a API se encarrega do resto.

Quero adicionar uma mensagem via bundle para um componente específico, posso?

– Sim. Chame o método addTranslateContext() passando o componentId,variavelBundle e key do bundle

Preciso adicionar uma mensagem para um component, informar a serverity e a mensagem direta. É possível?

– Sim, chame addMessageFaceContext(componentid,serverity, message)

 Preciso adicionar apenas uma mensagem ao contexto, como fazer?

Chame addFacesMessages() passando o FacesContext e  a mensagem que deseja

 Como adicionar uma mensagem para um severity específico sem especificar o component Id?

Chamando  addMessageFaceContext(severity,message).

GitHub 

https://github.com/camilolopes/I4JSF-API

Example Project

https://github.com/camilolopes/I4JSFDEMO

Vou ficando por aqui e aguardo os forks de vocês

Abraços, see ya!!! 

Série CI: Rodando o Jenkins a partir do Jetty no Windows 7

Olá Pessoal,

Estarei começando uma pequena série de posts de Integração contínua usando o Jenkins. Em um dos posts vamos conectar o jenkins com o github e qualquer alteração no repositório o build começa. Mas antes de chegar lá vamos passar por outros posts importantes também : )  keep calm and develop.

No post de hoje veremos como rodar o Jenkins dentro do Jetty. Algo super simples.

Lets go..

Starting…

Essa é uma opção de termos o jenkins rodando, mas você pode fazer o download do package de acordo com o seu sistema operacional e instalar o jenkins diretamente. Não sei se há muitas vantagens entre as duas opções, mas particularmente prefiro ter um servidor e fazer o deploy do .war do jenkins.

Requisitos

Faça o download de uma versão do jetty. Vou usar o jetty 7.x porque é o que tenho aqui na máquina, porém há versões mais recentes: http://jetty.codehaus.org/jetty/

Após o download do jetty, descompate o arquivo:

 

jettydescompactadao

Abra o prompt de comando do Windows e vá até o local onde está a pasta do jetty:

 

cijettycmd

Podemos iniciar o Jetty só para ver se está tudo ok com ele, então digite:

java –jar  start.jar

 

cijettyjavajarstart

E aguarde o jetty iniciar. Após a inicialização do jetty acesse HTTP://localhost:8080

Você verá o seguinte:

 

cijettyrunning

Pronto, temos o jetty rodando. Isso é bom.

Agora vamos parar o jetty para fazer o deploy do Jenkins. Pare a aplicação com ctrl + C.

Vá no site do jenkins e baixe a versão .war.  (estou usando a última versão)

Após ter baixado o .war coloque o mesmo na pasta webapps, dentro do diretório do jetty que você descompactou ainda pouco:

No meu caso:

jetty-distribution-7.0.0.v20091005\jetty-distribution-7.0.0.v20091005\webapps

Agora, inicie o servidor Jetty novamente java  -jar start.jar

E precisamos aguardar o jetty fazer o deploy do jenkins. Na primeira vez será um pouco demorado. Após o jetty concluir o trabalho dele, vamos ver se o jenkins realmente foi deployed. Acesse http://localhost:8080/jenkins/ e verá:

cijenkinsdeployed

No meu caso, tenho um job criado no jenkins, mas não se preocupe, pois faremos um no próximo post.

Por hoje é isso apenas.

Abracos, see ya!!