Olá, estou com o seguinte problema:
Tenho uma tabela servico com relacionamento n:n com uma tabela parceiros, assim existe uma tabela auxiliar chamada parceiros_has_servicos. O problema é que após vincular um parceiro a um serviço e fazer uma alteraçao no nome do serviço o registro na tabela auxiliar é deletado. Estou usando Hibernate para o mapeamento. Por favor aguardo esclarecimentos.
[RESOLVIDO]Update na tabela mãe causa delete dos registros na tabela filha
8 Respostas
Olá, Elieber!
Dá uma “brincada” com o mapeamento de sua entity class modifcando o CascadeType para ver se resolve.
té+
Eaí cara,
posta o código aí pra gente ver, mas isso aí é coisa de Cascade mesmo, como disse o apferreira.
Obrigado pelas respostas, abaixo segue o código dos mapeamentos:
mapeamento da tabela servicos.
@Entity
@Table(name = "servicos", catalog = "festas")
public class Servicos implements java.io.Serializable {
private int id;
private String descservico;
private Set<Orcamentocliente> orcamentoclientes = new HashSet<Orcamentocliente>(
0);
private Set<Parceiros> parceiroses = new HashSet<Parceiros>(0);
public Servicos() {
}
public Servicos(String descservico,
Set<Orcamentocliente> orcamentoclientes, Set<Parceiros> parceiroses) {
this.descservico = descservico;
this.orcamentoclientes = orcamentoclientes;
this.parceiroses = parceiroses;
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "descservico", length = 45)
public String getDescservico() {
return this.descservico;
}
public void setDescservico(String descservico) {
this.descservico = descservico;
}
@ManyToMany(fetch = FetchType.LAZY)
@Cascade(CascadeType.ALL)
@JoinTable(name = "orcamentocliente_has_servicos", catalog = "festas", joinColumns = { @JoinColumn(name = "servicos_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "orcamentocliente_id", nullable = false, updatable = false) })
public Set<Orcamentocliente> getOrcamentoclientes() {
return this.orcamentoclientes;
}
public void setOrcamentoclientes(Set<Orcamentocliente> orcamentoclientes) {
this.orcamentoclientes = orcamentoclientes;
}
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "parceiros_has_servicos", catalog = "festas", joinColumns = { @JoinColumn(name = "servicos_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "parceiros_pessoa_id", nullable = false, updatable = false) })
public Set<Parceiros> getParceiroses() {
return this.parceiroses;
}
public void setParceiroses(Set<Parceiros> parceiroses) {
this.parceiroses = parceiroses;
}
}
e da tabela parceiros
@Entity
@Table(name = "parceiros", catalog = "festas")
public class Parceiros implements java.io.Serializable {
private int pessoaId;
private Pessoa pessoa;
private String docparceiro;
private String nomecontato;
private Set<Servicos> servicoses = new HashSet<Servicos>(0);
public Parceiros() {
}
public Parceiros(Pessoa pessoa) {
this.pessoa = pessoa;
}
public Parceiros(Pessoa pessoa, String docparceiro, String nomecontato,
Set<Servicos> servicoses) {
this.pessoa = pessoa;
this.docparceiro = docparceiro;
this.nomecontato = nomecontato;
this.servicoses = servicoses;
}
@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "pessoa"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "pessoa_id", unique = true, nullable = false)
public int getPessoaId() {
return this.pessoaId;
}
public void setPessoaId(int pessoaId) {
this.pessoaId = pessoaId;
}
@OneToOne(fetch = FetchType.LAZY)
@Cascade(CascadeType.ALL)
@PrimaryKeyJoinColumn
public Pessoa getPessoa() {
return this.pessoa;
}
public void setPessoa(Pessoa pessoa) {
this.pessoa = pessoa;
}
@Column(name = "docparceiro", length = 45)
public String getDocparceiro() {
return this.docparceiro;
}
public void setDocparceiro(String docparceiro) {
this.docparceiro = docparceiro;
}
@Column(name = "nomecontato", length = 45)
public String getNomecontato() {
return this.nomecontato;
}
public void setNomecontato(String nomecontato) {
this.nomecontato = nomecontato;
}
@ManyToMany(fetch = FetchType.LAZY)
@Cascade(CascadeType.DELETE)
@JoinTable(name = "parceiros_has_servicos", catalog = "festas", joinColumns = { @JoinColumn(name = "parceiros_pessoa_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "servicos_id", nullable = false, updatable = false) })
public Set<Servicos> getServicoses() {
return this.servicoses;
}
public void setServicoses(Set<Servicos> servicoses) {
this.servicoses = servicoses;
}
}
e o da tabela auxiliar
@Entity
@Table(name = "parceiros_has_servicos", catalog = "festas")
public class ParceirosHasServicos implements java.io.Serializable {
private ParceirosHasServicosId id;
private Servicos servicos;
private Parceiros parceiros;
private BigDecimal valorservico;
private Boolean servicoativo;
public ParceirosHasServicos() {
}
public ParceirosHasServicos(ParceirosHasServicosId id, Servicos servicos,
Parceiros parceiros) {
this.id = id;
this.servicos = servicos;
this.parceiros = parceiros;
}
public ParceirosHasServicos(ParceirosHasServicosId id, Servicos servicos,
Parceiros parceiros, BigDecimal valorservico, Boolean servicoativo) {
this.id = id;
this.servicos = servicos;
this.parceiros = parceiros;
this.valorservico = valorservico;
this.servicoativo = servicoativo;
}
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name = "parceirosPessoaId", column = @Column(name = "parceiros_pessoa_id", nullable = false)),
@AttributeOverride(name = "servicosId", column = @Column(name = "servicos_id", nullable = false)) })
public ParceirosHasServicosId getId() {
return this.id;
}
public void setId(ParceirosHasServicosId id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "servicos_id", nullable = false, insertable = false, updatable = false)
public Servicos getServicos() {
return this.servicos;
}
public void setServicos(Servicos servicos) {
this.servicos = servicos;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parceiros_pessoa_id", nullable = false, insertable = false, updatable = false)
public Parceiros getParceiros() {
return this.parceiros;
}
public void setParceiros(Parceiros parceiros) {
this.parceiros = parceiros;
}
@Column(name = "valorservico", precision = 11)
public BigDecimal getValorservico() {
return this.valorservico;
}
public void setValorservico(BigDecimal valorservico) {
this.valorservico = valorservico;
}
@Column(name = "servicoativo")
public Boolean getServicoativo() {
return this.servicoativo;
}
public void setServicoativo(Boolean servicoativo) {
this.servicoativo = servicoativo;
}
}
apferreira, eu já havia mudado o CascadeType, e mesmo assim continua fazendo a mesma coisa. Alguma outra idéia?
Fala ae, Elieber!
Kra, se eu fosse você, continuaria “brincando” com os CascadeType.
Eu uso o EclipseLink mas não deve ser mto diferente do Hibernate. Normalmente, eu retiro todos os CascadeType.ALL. Só utilizo esta anotação se for realmente necessário. CascadeType.PERSIST tem sido mto mais comum para mim.
Outra coisa, dá uma olhada naquela anotação que você tem como CascadeType.DELETE. Tenta retirá-la ou mudá-la para ver o que acontece.
té+
Olá a todos, ainda não consegui resolver o problema citado. Entretanto estou pensando que o proplema possa ser nesta parte do codigo:
private Set<Parceiros> parceiroses = new HashSet<Parceiros>(0);
ou seja na minha Entity de servicos exite um HashSet de Parceiros, para cada serviço exite um coleção de parceiros. Minha dúvida é se no momento em que eu faço o update no serviço eu tenho que popular esta coleçao ? ou isso é feito automáticamente pelo Hibernate?. Não sei se fui claro na explicação, mas se alguem puder tirar esta duvida de como trabalhar com este HashSet eu agradeço.
Só pra esclarecer eu já retirei todos os CascadeType, e mesmo assim ao mudar por exlemplo a descriçao do serviço os dados da tabela auxiliar continuam sendo deletados.
Como eu havia imaginado na hora de recuperar os dados do serviço no banco o HashSet estava vindo vazio, e o hibernate entende que se um hashset esta vazio ele deve apagar os dados da tabela auxiliar, assim para resolver bastou popular a coleção de parceiros vinculados ao serviço a ser atualizado e pronto os dados da tabela auxiliar foram mantidos.
o codigo que usei foi esse:
ServicosDosParceirosDAO parceirosservicosDao = new ServicosDosParceirosDAO();
List<ParceirosHasServicos> listServicosVinc = parceirosservicosDao.listServicosVinculados(this.servicos.getId());
this.servicos.setParceiroses(new HashSet<Parceiros>());
if(listServicosVinc.size() > 0){
for(ParceirosHasServicos parceiros : listServicosVinc){
this.servicos.getParceiroses().add(parceiros.getParceiros());
}
this.servicosDao.inserirServico(this.servicos);
}
else{
this.servicosDao.inserirServico(this.servicos);
}
obrigado a todos que responderam a meu questionamento.