Spring-Data Jpa + hibernate. Problema com delete()
10 respostas
javamysqlspring
thimor
Estou utilizando Spring-DataJPA com Hibernate e estou com problema no método delete() da interface JpaRepository.
Quando eu chamo o método delete passando o objeto, determinados objetos ele exclui, outros objetos ele não exclui. Passa pelo método, não da exceção, e simplesmente nao exclui. Quando eu uso o delete passando o ID funciona. Alguém sabe explicar por que isso acontece?
Coloque a implementação dessa interface na sua pergunta?
thimor
as interfaces sao do spring-jpa nao sei as classes que as implementam. vou procurar no manual
jacoboliveira
Ola thimor, vou tentar explicar e depois mostrar a solução, certo? Vamos lá, do jeito que VC esta fazendo provavelmente VC não esta recuperando do banco o objeto categoria, pois se uma hora ele insere e outra hora ele não insere isso é devido a um conceito do hibernate que a gente chama de entidade gerenciada pelo hibernate, quando vc faz um findbyid VC esta recuperando uma entidade com uma informação a mais e quem faz isso é chamado Proxy, este faz o trabalho de conter esta informação a mais chamada de managed /gerenciado
Agora se ele esta managed então ele esta pronto para persistente state/estado de persistência
Solução
Dai VC pode dizer mais antes eu deletar por id, mas ai tem outros situações, por exemplo chave compostas ou até mesmo padrão de codificação de sempre passar um objeto pra fazer as operações de persistência e etc
thimor
ola bom dia. Foi a primeira coisa que tentei. fazer um find e mandar deletar. Porem nao deu certo. Eu acredito que seja por causa do relacionamento esse problema. Cada categoria recebe um id da tabela setor.
Entao em todos os relacionamentos 1-N a tabela que recebe o ID eu nao consigo excluir por esse metodo delete. Eu acho estranho pq como eh uma tabela “filha” ela nao deveria ter restrição de delete.
jacoboliveira
Mostra a entidade categoria pra mim, por favor
thimor
@EntitypublicclassSecaoimplementsSerializable{privatestaticfinallongserialVersionUID=1L;@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateIntegerid;@Column(name="nome",length=30,nullable=false)privateStringnome;@OneToMany(cascade=CascadeType.ALL,mappedBy="secao",fetch=FetchType.LAZY)privateList<Categoria>categorias;@OneToMany(cascade=CascadeType.ALL,mappedBy="secao",fetch=FetchType.LAZY)privateList<Familia>familias;publicSecao(){}//gets e sets}@Entity@Table(name="categoria")publicclassCategoriaimplementsSerializable{privatestaticfinallongserialVersionUID=1L;@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateIntegerid;@Column(name="nome",length=30,nullable=false)privateStringnome;@JoinColumn(name="id_secao",referencedColumnName="id",nullable=false)@ManyToOne(optional=false)privateSecaosecao;@OneToMany(cascade=CascadeType.ALL,mappedBy="categoria",fetch=FetchType.LAZY)privateList<Familia>familias;publicCategoria(){secao=newSecao();}//gets e sets}
jacoboliveira
Olha thimor até agora não vi nada de errado tem que ver se o objeto Categoria esta vindo com o id tenta “debugar”, outra coisa mostra a classe família para eu ver, e ter certeza que esta tudo mapeado certo
igor_ks2 likes
Tente sobreescrever os métodos equals e hashCode. Pode ser que o Sprint-data não esteja achando o objeto igualzinho ao passado, por causa da falta do equals e hashCode, mesmo que seja os mesmos valores
thimor
a classe Secao, apaga com o metodo delete(T t). as classes Categoria e Familia so apagam com o delete(ID id)
@Entity@Table(name="familia")publicclassFamiliaimplementsSerializable{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateIntegerid;@Column(name="nome",length=30,nullable=false)privateStringnome;@JoinColumn(name="id_secao",referencedColumnName="id",nullable=false)@ManyToOne(optional=false)privateSecaosecao;@JoinColumn(name="id_categoria",referencedColumnName="id",nullable=false)@ManyToOne(optional=false)privateCategoriacategoria;publicFamilia(){secao=newSecao();categoria=newCategoria();}//gets e sets}
L
Logusmao
thimor,
Como o igor_ks disse, parece ser um problema de escolha dos métodos equals e hashCode. Na hora de realizar o delete, se os parâmetros não baterem exatamente, ele simplesmente não os identifica (e portanto não os deleta) sem retornar qualquer informação de falha para o usuário.
Outra coisa, se você estiver usando JPA 2.0, nos atributos @XXXtoMany você pode usar orphanRemoval=true.