Erro relacionamento oneToMany JPA

Boa tarde pessoal, estou fazendo um exemplo de relacionamento OntToMany usando JPA e está acontecendo um erro que nao consegui resolver ainda, alguém pode me ajudar por favor:

Tabelas:

CREATE TABLE cliente (
identificador INTEGER NOT NULL AUTO_INCREMENT,
nome VARCHAR(45) NOT NULL,
PRIMARY KEY(identificador)
) ENGINE = InnoDB;

CREATE TABLE endereco (
identificador INTEGER NOT NULL AUTO_INCREMENT,
rua VARCHAR(45) NOT NULL,
identificador_cliente INTEGER NOT NULL,
PRIMARY KEY(identificador),
CONSTRAINT FK_cliente
FOREIGN KEY FK_endereco(identificador_cliente)
REFERENCES cliente (identificador)
ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB;

Model Cliente:

@Entity
public class Cliente {

    private int id;

    private String nome;

    private List<Endereco> enderecos = new ArrayList<Endereco>();

    @OneToMany(cascade = { CascadeType.PERSIST })
    public List<Endereco> getEnderecos() {
        return enderecos;
    }

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

    @Id
    @Column(name = "identificador")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void addEndereco(Endereco endereco) {
        enderecos.add(endereco);
    }
}

Model Endereco:

@Entity
public class Endereco {

    public Endereco() {

    }

    public Endereco(String rua) {
        this.rua = rua;
    }

    private int id;

    private String rua;

    @Id
    @Column(name = "identificador")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRua() {
        return rua;
    }

    public void setRua(String rua) {
        this.rua = rua;
    }
}

DAO:

public class BaseDAO<T> {

    private static EntityManagerFactory mf;

    private EntityManager em;

    public BaseDAO() {
        mf = Persistence.createEntityManagerFactory("pu1");
        em = mf.createEntityManager();
    }

    public void salvar(T obj) {

        em.getTransaction().begin();
        try {
            em.persist(obj);
            em.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            em.getTransaction().rollback();
        }
    }
}

TesteDAO:

public class TesteDAO {

    public static void main(String[] args) {
        BaseDAO<Cliente> dao = new BaseDAO<Cliente>();

        Endereco ed = new Endereco();
        ed.setRua("Rua dos loucos");

        Cliente c = new Cliente();
        c.setNome("Silvio");
        c.addEndereco(ed);

        dao.salvar(c);

    }
}

Erro:

Internal Exception: java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails (`unicodono/endereco`, CONSTRAINT `FK_cliente` FOREIGN KEY (`identificador_cliente`) REFERENCES `cliente` (`identificador`))Error Code: 1452
Call:INSERT INTO ENDERECO (RUA) VALUES (?)
	bind => [Rua dos loucos]

Obrigado, estarei no aguardo pra quem puder me jaudar…

[]'s

oi alberto,
eu acho que faltou vc incluir o endereço (ou persisti-lo).
tente salvar o seu endereço antes d incluir o cliente:

public class TesteDAO {
 
     public static void main(String[] args) {
         BaseDAO<Cliente> dao = new BaseDAO<Cliente>();
 
         Endereco ed = new Endereco();
         ed.setRua("Rua dos loucos");
         // aqui!
         new BaseDAO<Endereco>().salvar(ed); 

         Cliente c = new Cliente();
         c.setNome("Silvio");
         c.addEndereco(ed);
 
         dao.salvar(c);
 
     }
 }

[]´s

Então facholi, cara eu imaginava a seguinte situação, antigamente lembro que no hibernate por exemplo eu queria salvar um cliente, então quando eu salva-se este cliente ele salvaria pra mim o endereço também, por causa do esquema de cascade que era responsável por armazenar-lo…

Endereco endereco = new Endereco();
endereco.setRua("Rua dos loucos");

Cliente cliente = new Cliente();
cliente.setNome("Silvio");

//adiciona o endereço no cliente
cliente.addEndereco(endereco);

dao.salvar(cliente);

Abs

Alguns comentários:

  • não deixa a lógica de controle transacional dentro de seus DAOs
  • faltou o lado ManyToOne de Endereço pra Cliente.

Bom dia plentz, então você diz pra eu não controlar a transação no DAO em que camada você indicaria, no Business Delegate ???

[]'s
Valeu pelas respostas

Depende muito de como suas camada estão organizadas e quais são. Mas definitivamente não dentro do DAO.

Obrigado pelas respostas…

[]'s

Estou fazendo uma aplicação muito parecida com a sua, inclusive fiz um addTelefone e tudo, mas não persiste de jeito nenhum, o id_pessoa da tabela telefone fica nulo sempre. Quando debuguei vi que estava sendo inserido todos os atributos de pessoa e endereco, mesmo a foreignkey id_pessoa.

Se puderem me ajudar ficarei grato :wink: