Bom dia colegas,
Estou com uma dúvida no mapeamento de coleções. Estou usando o Hibernate JPA 2.0.
Tenho uma classe Funcionario e uma classe Telefone. Dessa forma, dentro da classe funcionário tem uma lista de Telefones e dentro de Telefone tem uma lista de Funcionarios. Realizei o mapeamento bidirecional da seguinte forma:
Na classe Telefone
@JoinColumn(name = "funcionario", referencedColumnName = "funcionario")
@ManyToOne(optional = false)
private Funcionario funcionario;
No caso, a coluna funcionário é NOT NULL no banco.
Na classe Funcionario
@OneToMany(cascade = CascadeType.ALL, mappedBy = "funcionario", fetch = FetchType.EAGER)
private Collection<Telefone> listaTelefones;
Minha dúvida é a seguinte: Existe alguma maneira de inserir um objeto telefone dentro de listaTelefones SEM SETAR O ATRIBUTO FUNCIONARIO dentro de Telefone, de modo que o hibernate atribua o funcionário automaticamente na hora da persistência? Acredito que deva existir um jeito, pois se o telefone está dentro da lista, o funcionário deve ser o dono da lista. Alguém saberia me informar?
Muito Obrigado
Deixa eu entender, um relacionamento N : 1 você tem uma coluna NOT NULL e quer inserir nesta tabela, sem ter um registro associado?
Não.
A não ser que você possua um DEFAULT VALUE para a coluna, aí sim, mas, creio que já tenha sido criada a constraint que não permite inserir valores que não estejam associados à uma tupla em funcionário.
Ao meu ver, a não nulidade da coluna está errada. A não ser que, obrigatoriamente, todo telefone pertença a um funcionário.
[quote=drsmachado]Deixa eu entender, um relacionamento N : 1 você tem uma coluna NOT NULL e quer inserir nesta tabela, sem ter um registro associado?
Não.
A não ser que você possua um DEFAULT VALUE para a coluna, aí sim, mas, creio que já tenha sido criada a constraint que não permite inserir valores que não estejam associados à uma tupla em funcionário.
Ao meu ver, a não nulidade da coluna está errada. A não ser que, obrigatoriamente, todo telefone pertença a um funcionário.[/quote]
Acho que o que ele quer é que quando fizer algo assim:Funcionario funcionario = new Funcionario();
funcionario.setListaTelefones(new ArrayList<Telefone>());
Telefone telefone = new Telefone("8888-8888");
funcionario.getListaTelefones.add(telefone);
FuncionarioDAO dao = new FuncionarioDAO();
dao.salvar(funcionario);
Com um código parecido com esse, no momento da persistência, o Hibernate atribuir a cada telefone, a referência de Funcionário, sem que isso precisa ser declarado explicitamente, assim:telefone.setFuncionario(funcionario);
Exatamente digaoneves.
De acordo com as regras de negócio da aplicação, o banco está certo. De fato, todo telefone pertence a um funcionário.
O problema acontece, porque no formulário de cadastro de funcionário já tem espaço para cadastrar uma lista de telefones. No entanto, como o cadastro de Funcionario e Telefone está sendo feito ao mesmo tempo, eu não posso associar o funcionário dentro de Telefone, uma vez que ele ainda não foi criado. Por isso, vou adicionando os telefones na lista dentro do funcionário (SEM setar o Funcionário).
Quando eu salvo o funcionário, ele tenta persistir os elementos da lista de telefone, mas (por causa do NOT NULL) ocorre uma Exception.
Uma solução seria, antes de chamar o DAO, varrer a lista de telefones e ir fazendo telefone.setFuncionario(funcionario). Mas pensei que pudesse existir uma forma do Hibernate fazer isso automaticamente…
Eu normalmente itero, ou seto na hora de adicionar o objeto à lista. não sei se existe algo que faça isso da maneira que você quer.
O jeito é você criar um objeto default. Criou um func novo, adiciona um telefone lá mesmo que não tenha valor algum.
eu imaginei algo como:[code]class Funcionario{
//Outros atributos
List<Telefone> telefones;
public void adicionarTelefone(Telefone telefone){
telefones.add(telefone);
telefone.setFuncionario(this);
}
//Outros métodos
}[/code]Mas claro, lembre-se de inicializar a lista antes de invocar o método. Talvez até no próprio método, se for tratado corretamente, ou no construtor, se for viável.
Obrigado a todos…
O jeito do jakefrog e o jeito que o digaoneves, ambos funcionaram…
Talvez isso não é possível de ser feito de forma automática pelo hibernate.