JPA CascadeType.ALL faz órfãos não de exclusão
Pergunta
Estou tendo problemas para eliminar os nós órfãos usando JPA com o seguinte mapeamento
@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner")
private List<Bikes> bikes;
Estou tendo a questão dos papéis órfãs hanging em torno do banco de dados.
Eu posso usar a tag Hibernate específica anotação org.hibernate.annotations.Cascade
mas, obviamente, eu não quero amarrar a minha solução para uma implementação Hibernate.
Editar :. Parece JPA 2.0 vai incluir suporte para este
Solução
Se você estiver usando-o com Hibernate, você terá que definir explicitamente a CascadeType.DELETE_ORPHAN
anotação, que pode ser usado em conjunto com JPA CascadeType.ALL
.
Se você não planeja usar o Hibernate, você vai ter que explicitamente primeiro excluir os elementos filhos e, em seguida, excluir o registro principal para evitar quaisquer registros órfãos.
sequência de execução
- buscar linha principal a ser eliminado
- buscar elementos filhos
- apagar todos os elementos filhos
- Excluir linha principal
- close sessão
Com JPA 2.0, agora você pode usar a opção orphanRemoval = true
@OneToMany(mappedBy="foo", orphanRemoval=true)
Outras dicas
Se você estiver usando JPA 2.0, agora você pode usar o atributo orphanRemoval=true
da anotação @xxxToMany
para remover órfãos.
Na verdade, CascadeType.DELETE_ORPHAN
foi depreciado em 3.5.2-final.
╔═════════════╦═════════════════════╦═════════════════════╗
║ Action ║ orphanRemoval=true ║ CascadeType.ALL ║
╠═════════════╬═════════════════════╬═════════════════════╣
║ delete ║ deletes parent ║ deletes parent ║
║ parent ║ and orphans ║ and orphans ║
╠═════════════╬═════════════════════╬═════════════════════╣
║ change ║ ║ ║
║ children ║ deletes orphans ║ nothing ║
║ list ║ ║ ║
╚═════════════╩═════════════════════╩═════════════════════╝
Se você estiver usando JPA com EclipseLink, você terá que definir o @PrivateOwned anotação.
Documentação: Eclipse Wiki - Usando EclipseLink JPA Extensões - Capítulo 1.4 Como usar o @PrivateOwned anotação
Você pode usar @PrivateOwned aos órfãos de exclusão por exemplo
@OneToMany(mappedBy = "masterData", cascade = {
CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;
De acordo com a Java Persistence com Hibernate , cascata órfão excluir não está disponível como uma anotação JPA.
Ele também não é suportado em XML JPA.
Eu só encontrar essa solução, mas no meu caso ele não funciona:
@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true)
orphanRemoval = true não tem efeito.
Eu tive o mesmo problema e eu me perguntava por esta condição abaixo não excluir os órfãos. A lista de pratos não foram excluídos em Hibernate (5.0.3.Final) quando executada uma consulta de exclusão chamado:
@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Dish> dishes = new ArrayList<>();
Então me lembrei que eu não deve usar uma consulta de exclusão denominado , mas o EntityManager. Como eu usei o método EntityManager.find(...)
para buscar a entidade e, em seguida, EntityManager.remove(...)
excluí-lo, os pratos foram excluídos.
Apenas @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true)
.
Remove targetEntity = MyClass.class , ele funciona muito bem.
Para os registros, em OpenJPA antes JPA2 era @ElementDependant.
Eu estava usando o mapeamento um para um, mas criança não estava ficando excluído JPA foi que dá a chave violação estrangeira
Depois de usar orphanRemoval = true, assuntos ficou resolvido