Digamos que eu tenha um relacionamento unidirecional @ManyToOne
como o seguinte:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
}
@Entity
public class Child implements Serializable {
@Id
@GeneratedValue
private long id;
@ManyToOne
@JoinColumn
private Parent parent;
}
Se eu tiver um pai P e filhos C 1 ... C n referenciando P, existe uma maneira limpa e bonita em JPA de remover automaticamente os filhos C 1 ... C n quando P é removido (isto é entityManager.remove(P)
)?
O que procuro é uma funcionalidade semelhante ao ON DELETE CASCADE
SQL.
java
jpa
jpa-2.0
many-to-one
criminoso
fonte
fonte
Respostas:
Os relacionamentos em JPA são sempre unidirecionais, a menos que você associe o pai ao filho em ambas as direções. As operações REMOVE em cascata dos pais para os filhos exigirão uma relação dos pais para os filhos (não apenas o oposto).
Portanto, você precisará fazer o seguinte:
@ManyToOne
relacionamento unidirecional para bidirecional@ManyToOne
ou unidirecional@OneToMany
. Você pode então colocar em cascata as operações REMOVE paraEntityManager.remove
remover o pai e os filhos. Você também pode especificarorphanRemoval
como verdadeiro, para excluir quaisquer filhos órfãos quando a entidade filha na coleção pai for definida como nula, ou seja, remover o filho quando não estiver presente em nenhuma coleção pai.ON DELETE CASCADE
. Você precisará invocarEntityManager.clear()
após a chamada,EntityManager.remove(parent)
pois o contexto de persistência precisa ser atualizado - as entidades filhas não deveriam existir no contexto de persistência depois de terem sido excluídas do banco de dados.fonte
Se você estiver usando o hibernate como seu provedor JPA, poderá usar a anotação @OnDelete. Esta anotação adicionará à relação a trigger ON DELETE CASCADE , que delega a exclusão dos filhos ao banco de dados.
Exemplo:
Com esta solução, um relacionamento unidirecional do filho para o pai é suficiente para remover automaticamente todos os filhos. Esta solução não precisa de nenhum ouvinte, etc. Além disso, uma consulta como DELETE FROM Parent WHERE id = 1 removerá os filhos.
fonte
@OneToOne
Alguma idéia de como resolver isso@OneToOne
?Crie uma relação bidirecional, como esta:
fonte
Eu vi em @ManytoOne unidirecional, a exclusão não funciona como esperado. Quando o pai é excluído, o ideal é que o filho também seja excluído, mas apenas o pai é excluído e o filho NÃO é excluído e fica órfão
A tecnologia usada é Spring Boot / Spring Data JPA / Hibernate
Inicialização Sprint: 2.1.2.RELEASE
Spring Data JPA / Hibernate é usado para excluir a linha.
parentRepository.delete(parent)
ParentRepository estende o repositório CRUD padrão como mostrado abaixo
ParentRepository extends CrudRepository<T, ID>
A seguir estão minha classe de entidade
fonte
spring.jpa.hibernate.use-new-id-generator-mappings=true spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
"
no código. Vejaname= "parent"
Use esta forma para apagar apenas um lado
fonte
@Cascade (org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
A anotação dada funcionou para mim. Pode tentar
Por exemplo :-
fonte