terça-feira, 29 de junho de 2010

Hibernate Exception: Illegal attempt to associate a collection with two open sessions

Esse problema começou a correr quando passei a utilizar o pattern (Open Session In View). E ocorre quando temos uma collection, por exemplo, em um relacionamento @OneToMany.


No meu caso, quando eu adicionava um objeto a collection dava tudo certo:

public void saveMensagem(ActionEvent event){
   dao = new ChamadoDao<Chamado>(HibernateUtil.getSession(),Chamado.class);
   try{
      mensagem.setChamado(chamado);
      mensagem.setUsuario(LoginMB.getUsuarioLogado());
      chamado.getMensagens().add(mensagem);
      dao.update(chamado);
   }catch (Exception e) {
      e.printStackTrace();
   }
}

O problema ocorria quando eu fazia um update no objeto que contem a collection, sem fazer alterações na mesma:

public void save(ActionEvent event){
   dao = new ChamadoDao<Chamado>(HibernateUtil.getSession(),Chamado.class);
   try{
      if(chamado.getUsuario() == null){
         chamado.setUsuario(LoginMB.getUsuarioLogado());
         dao.save(chamado);
      }else{
         dao.update(chamado);
      }
   }catch (Exception e) {
      e.printStackTrace();
   }
}


Para resolver o problema eu mudei de session.update para session.merge:

public void save(ActionEvent event){
   dao = new ChamadoDao<Chamado>(HibernateUtil.getSession(),Chamado.class);
   try{
      if(chamado.getUsuario() == null){
         chamado.setUsuario(LoginMB.getUsuarioLogado());
        dao.save(chamado);
      }else{
         dao.merge(chamado);
      }
   }catch (Exception e) {
      e.printStackTrace();
   }
}

quarta-feira, 23 de junho de 2010

Layout do teclado altera automaticamente no Eclipse

Utilizando o editor do Eclipse, ao pressionar as teclas (ALT"Esquerda"+SHIFT) o layout do teclado é alterado para inglês, pressionando novamente as teclas de atalho ele volta ao normal.

Essa alteração não é feita pelo Eclipse e sim pelo Windows. Isso acaba causando alguns transtornos quando não sabemos as teclas que pressionamos, e é necessário reiniciar o Eclipse para a configuração voltar ao normal.

Para desativar ou alterar as teclas de atalho você deve ir em: Configurações regionais no seu Windows -> Idiomas -> Detalhes -> Configurações de tecla.

segunda-feira, 21 de junho de 2010

Porque evitar o saveOrUpdate do Hibernate?

Para o Hibernate saber se o saveOrUpdate deve fazer um insert ou um update, ele faz um select na tabela e verifica se o registro já existe, caso exista ele faz um update do contrário um insert. Com isso temos uma ida adicional ao banco de dados.

Para evitar o select adicional você pode utilizar um mapeamento <Version> ou <TimeStamp> e uma propriedade na entidade. O Hibernate gerencia os valores internamente para controle de concorrência otimista, um dos efeitos desse gerenciamento é que um valor de data e hora vazia ou uma versão 0 ou null, indica que é uma instância nova e a mesma será automaticamente inserida, sem que um select seja efetuado.

Ou utilize os métodos save e update separadamente.

sábado, 19 de junho de 2010

java.io.NotSerializableException: org.hibernate.util.MarkerObject

Problema

java.io.NotSerializableException: org.hibernate.util.MarkerObject

Ao utilizar o a4j:keepAlive nos arquivos jsf, o mesmo exige que o Managed Bean e suas dependências implementem Serializable. Porém, a classe MarkerObject do hibernate (versão 3.3.2.GA) não implementa.

Solução

Implementar Serializable na classe MarkerObject

1) Edite o arquivo (hibernate-distribution-3.3.2.GA\project\core\src\main\java\org\hibernate\util\MarkerObject.java).

2) Implemente Serializable na classe. Deve ficar assim:
     import java.io.Serializable;
     public class MarkerObject implements Serializable{

3) Execute javac MarkerObject.java. Isso vai gerar o arquivo MarkerObject.class.

4) Descompacte o arquivo (hibernate-distribution-3.3.2.GA\hibernate3.jar).

5) Substitua o arquivo (hibernate3\org\hibernate\util\ MarkerObject.class) pelo arquivo .class gerado no passo 3.

6) Gere o arquivo .jar com (jar cvfm) ou utilize um programa que faça compactação jar.
A raiz do novo arquivo hibernate3.jar deve ser igual ao original com os seguintes diretórios: META-INF e org.

7) Substitua o arquivo hibernate3.jar do diretório lib da sua aplicação ou do seu JBoss pelo arquivo gerado no passo 5.

Você pode utilizar o exemplo acima para fazer outras customizações no código fonte do hibernate.

segunda-feira, 14 de junho de 2010

Converter 0 em null

Problema

JSF retorna 0 (Zero) quando o valor não é preenchido.
Ex: Existe uma propriedade no Bean chamada (idade) e um inputText no JSF vinculado a propriedade do Bean. Quando o valor não é preenchido no inputText o JSF retorna 0 para o Bean, quando deveria retornar null.

Solução

Edite o arquivo \jboss-5.1.0.GA\server\default\deploy\properties-service.xml e insira a tag:

<attribute name="Properties">org.apache.el.parser.COERCE_TO_ZERO=false</attribute>

dentro da tag:
<mbean code="org.jboss.varia.property.SystemPropertiesService" name="jboss:type=Service,name=SystemProperties">