JPA - Hibernate

Então, to fazendo um projeto utilizando hibernate pra persistência mas estou com um problema.

Tenho duas entidades, Pessoa e Endereco.

A Pessoa tem uma lista de Endereco, mapeada assim:

@OneToMany(mappedBy="pessoa") private List<Endereco> enderecos;

Então achei que ao mandar salvar a pessoa, por ela estar com os endereços que quero associar a ela na lista, o hibernate fosse sozinho pôr o código da pessoa na tabela de endereço que esta assim:

±--------------±-------------±-----±----±--------±---------------+
| Field | Type | Null | Key | Default | Extra |
±--------------±-------------±-----±----±--------±---------------+
| cdEndereco…| int(11)…| NO | PRI | NULL | auto_increment |
| nmLogradouro…| varchar(100)| NO |…| NULL | |
| nuNumero…| int(11)…| NO |…| NULL | |
| deComplemento | varchar(100)| YES |…| NULL | |
| nuCep…| varchar(10)…| NO |…| NULL | |
| cdPessoa…| int(11)…| YES | MUL | NULL | |
±--------------±-------------±-----±----±--------±---------------+

onde cdPessoa é uma chave para tabela de pessoa.

Mas quando mando salvar a pessoa com endereços na lista, é como se a lista estivesse vazia pois não muda nada…

É isso se precisarem de mais informação é só pedir.

Agradeço desde já.

cara,

coloca nesse seu mapeamento cascade do tipo all, deve funcionar.

t+

Não resolveu o cascade all…

Até encontrar a solução correta só consegui através de uma pog… Na hora de salvar a pessoa, se existirem endereços na lista eu mando dar merge dos endereços com o código da pessoa.

A operação inversa esta funcionando, ele carrega sozinho os endereços que a pessoa tem.

cara,

posta suas entidades, para poder te ajudar.

t+

Seguem Pessoa e Endereço

[code]package br.com.trabalhofinal.domain;

import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;
import java.util.List;

@Entity
@Table(name=“pessoa”)
public class Pessoa implements Serializable {

private static final long serialVersionUID = 1160860134157050896L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int cdPessoa;
private String deEmail;
@Temporal( TemporalType.DATE)
private Date dtNascimento;
private String nmNome;
private String nuCpf;
private String nuRg;

@OneToMany(mappedBy="pessoa", cascade=CascadeType.ALL)
private List<Endereco> enderecos;

@OneToMany(mappedBy="pessoa")
private List<Usuario> usuarios;

public Pessoa() {
}

public int getCdPessoa() {
	return this.cdPessoa;
}

public void setCdPessoa(int cdPessoa) {
	this.cdPessoa = cdPessoa;
}

public String getDeEmail() {
	return this.deEmail;
}

public void setDeEmail(String deEmail) {
	this.deEmail = deEmail;
}

public Date getDtNascimento() {
	return this.dtNascimento;
}

public void setDtNascimento(Date dtNascimento) {
	this.dtNascimento = dtNascimento;
}

public String getNmNome() {
	return this.nmNome;
}

public void setNmNome(String nmNome) {
	this.nmNome = nmNome;
}

public String getNuCpf() {
	return this.nuCpf;
}

public void setNuCpf(String nuCpf) {
	this.nuCpf = nuCpf;
}

public String getNuRg() {
	return this.nuRg;
}

public void setNuRg(String nuRg) {
	this.nuRg = nuRg;
}

public List<Endereco> getEnderecos() {
	return this.enderecos;
}

public void setEnderecos(List<Endereco> enderecos) {
	this.enderecos = enderecos;
}

public List<Usuario> getUsuarios() {
	return this.usuarios;
}

public void setUsuarios(List<Usuario> usuarios) {
	this.usuarios = usuarios;
}

}[/code]

[code]package br.com.trabalhofinal.domain;

import java.io.Serializable;
import javax.persistence.*;

import br.com.trabalhofinal.utils.BaseEntity;

@Entity
@Table(name=“endereco”)
public class Endereco implements Serializable, BaseEntity {

private static final long serialVersionUID = -8264862318105516009L;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int cdEndereco;
private String deComplemento;
private String nmLogradouro;
private String nuCep;
private Integer nuNumero;

@ManyToOne
@JoinColumn(name="cdPessoa")
private Pessoa pessoa;

public Endereco() {
}

@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (!(obj instanceof Endereco)) {
        return false;
    }
    final Endereco other = (Endereco) obj;
    if (getNmLogradouro() == null) {
    	return false;
    }
    return getNuCep().equals(other.getNuCep());
}

@Override
public int hashCode() {
    return 0;
}

@Override
public Long getId() {
	return Long.valueOf(getCdEndereco());
}

public int getCdEndereco() {
	return this.cdEndereco;
}

public void setCdEndereco(int cdEndereco) {
	this.cdEndereco = cdEndereco;
}

public String getDeComplemento() {
	return this.deComplemento;
}

public void setDeComplemento(String deComplemento) {
	this.deComplemento = deComplemento;
}

public String getNmLogradouro() {
	return this.nmLogradouro;
}

public void setNmLogradouro(String nmLogradouro) {
	this.nmLogradouro = nmLogradouro;
}

public String getNuCep() {
	return this.nuCep;
}

public void setNuCep(String nuCep) {
	this.nuCep = nuCep;
}

public Integer getNuNumero() {
	return this.nuNumero;
}

public void setNuNumero(Integer nuNumero) {
	this.nuNumero = nuNumero;
}

public Pessoa getPessoa() {
	return this.pessoa;
}

public void setPessoa(Pessoa pessoa) {
	this.pessoa = pessoa;
}

}[/code]

cara,

como seu relacionamento é bidirecional, vc tem que preencher o objeto Pessoa com o endereco e o objeto Enderenco com a pessoa, vc ta fazendo isso?

t+

Não, só a pessoa com os endereços, e mandava salvar só a pessoa, achei que o hibernate fizesse o resto por mim :frowning:

então de fato tenho de preencher os endereços com a pessoa e dar merge neles tambem?

cara,

vc tem que fazer algo assim,

Pessoa pessoa = new Pessoa();

Endereco endereco = new Endereco();

pessoa.getEnderecos().add(pessoa);
endereco.setPessoa(pessoa);

t+

Seu mapeamento não está correto!

Como o relacionamento é “m x 1”…

1 pessoa tem 1 endereço( Objeto pessoa deve ter um objeto endereço )

1 endereço tem muitas pessoas ( Objeto endereço tem uma lista de pessoas )

Você fez o contrário!

Em Hibernate, quando a relação for “m x 1”… vc deve mapear dos dois lados! ManyToOne em 1 classe (Endereço) e OneToMany na classe Pessoa.

Quando for persistir os dados, vc cria o objeto endereço ( A lista de pessoas vem depois ), cria o(s) objeto(s) pessoa, preenche pessoa(s) insere na lista de endereço e persiste endereço.

public static void inserirEnderecoESeusMoradores(){
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("[Sua Unidade de Persistência]");
  EntityManager em = emf.createEntityManager();

  em.getTransaction();

  Endereco end = new Endereco();
  endereco.setnmLogradouro("logradouro");

  Pessoa pes1 = new Pessoa();
  pes1.setNome("Nome");
  pes1.setEndereco(end);
  
  Pessoa pes2 = new Pessoa();
  pes2.setNome("Nome");
  pes2.setEndereco(end);

  List<Pessoa> pList = ArrayList<Pessoa>();
  pList.add(pes1);
  pList.add(pes2);

  em.persist(end);

  em.commit();
  em.close();
  emf.close();
}

Espero ter ajudado!

[quote=leomamedio]Seu mapeamento não está correto!

Como o relacionamento é “m x 1”…

1 pessoa tem 1 endereço( Objeto pessoa deve ter um objeto endereço )

1 endereço tem muitas pessoas ( Objeto endereço tem uma lista de pessoas )

Você fez o contrário!

Em Hibernate, quando a relação for “m x 1”… vc deve mapear dos dois lados! ManyToOne em 1 classe (Endereço) e OneToMany na classe Pessoa.

Quando for persistir os dados, vc cria o objeto endereço ( A lista de pessoas vem depois ), cria o(s) objeto(s) pessoa, preenche pessoa(s) insere na lista de endereço e persiste endereço.

public static void inserirEnderecoESeusMoradores(){
  EntityManagerFactory emf = Persistence.createEntityManagerFactory("[Sua Unidade de Persistência]");
  EntityManager em = emf.createEntityManager();

  em.getTransaction();

  Endereco end = new Endereco();
  endereco.setnmLogradouro("logradouro");

  Pessoa pes1 = new Pessoa();
  pes1.setNome("Nome");
  pes1.setEndereco(end);
  
  Pessoa pes2 = new Pessoa();
  pes2.setNome("Nome");
  pes2.setEndereco(end);

  List<Pessoa> pList = ArrayList<Pessoa>();
  pList.add(pes1);
  pList.add(pes2);

  em.persist(end);

  em.commit();
  em.close();
  emf.close();
}

Espero ter ajudado!

[/quote]

Desculpe se o meu código não usa os comandos do hibernate. (Eu uso JPA com Hibernate), porisso os códigos talvez fiquem confusos para vc!
Mas vai dar para entender a lógica da coisa!

Boa sorte!