DWR e Hibernate

Ao utilizar estas duas ferramentas, deve-se tomar cuidado com alguns detalhes. No projeto em que trabalho temos um relacionamento entre duas classes, de um para muitos. É o relacionamento citado no post anterior a este, mas vou repetir. Temos a classe Documento que possui uma coleção de Signatarios.

A questão é que a classe Signatario contém um identificador composto, composite-id. Este identificador é representado por outra classe, chamada SignatarioPK. Nesta classe existe um relacionamento com Documento, do tipo Many To One.

@Entity
@Table(name="SIGNATARIO")
public class Signatario {

   @EmbbededId
   private SignatarioPK pk;

}

A classe SignatarioPK ficou assim:

@Embeddable
public class SignatarioPK implements Serializable {
   private Usuario usuario;
   private Documento documento;

   @ManyToOne(fetch=FetchType.EAGER)
   @Cascade(value={org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
   @JoinColumn(name="IDDOCUMENTO")
   public Documento getDocumento() {
      return documento;
   }

   public void setDocumento(Documento documento) {
      this.documento = documento;
   }

   @ManyToOne(fetch=FetchType.EAGER)
   @JoinColumn(name="IDUSUARIO")
   public Usuario getUsuario() {
      return usuario;
   }

   public void setUsuario(Usuario usuario) {
      this.usuario = usuario;
   }

}

Vamos ao problema. Toda nossa aplicação foi feita com DWR, portanto, esta ferramenta cria nossos objetos, de forma automática, a partir das informações do formulário. Cria, inclusive, os relacionamentos. Portanto, ele vai criar uma instância de Documento, depois uma instância de Signatario, uma instância de SignatarioPK, uma instância de Usuario e, aqui está o problema, uma nova instância de Documento para “setar” no relacionamento que existe entre SignatarioPK e Documento.

Quando mandamos salvar este objeto, criado da forma como citei, o registro na tabela fica com o campo referente ao identificador do documento como NULL. O correto seria o DWR ter usado a primeira instância de Documento que foi criada, para ter tipo uma referência circular: um documento que tem Signatários que tem o mesmo documento.

Por exemplo, em código, o que o DWR está fazendo é isto:

Documento doc = new Documento();
Signatario signatario = new Signatario();
SignatarioPK pk = new SignatarioPK();

Usuario usuario = new Usuario();
usuario.setId("valor do formulário");

// Criou uma nova instância de Documento. Era pra ter usado a variável doc acima.
Documento doc2 = new Documento();
doc2.setId("valor do formulário");
pk.setUsuario(usuario);
pk.setDocumento(doc2);

signatario.setPk(pk);
doc.getSignatarios.add(signatario);

Mas o correto seria isto:

Documento doc = new Documento();
doc.setId("valor do formulário");

Signatario signatario = new Signatario();
SignatarioPK pk = new SignatarioPK();

Usuario usuario = new Usuario();
usuario.setId("valor do formulário");

pk.setUsuario(usuario);
pk.setDocumento(doc);

signatario.setPk(pk);
doc.getSignatarios.add(signatario);

Entendeu? 🙂