JPA CascadeType.ALL não exclui órfãos

Estou tendo problemas para excluir nós órfãos usando o JPA com o seguinte mapeamento

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner") private List bikes; 

Eu estou tendo o problema das funções órfãs penduradas no database.

Eu posso usar a tag específica de anotação org.hibernate.annotations.Cascade Hibernate mas obviamente eu não quero amarrar minha solução em uma implementação do Hibernate.

EDIT : Parece JPA 2.0 includeá suporte para isso.

Se você estiver usando com o Hibernate, você terá que definir explicitamente a anotação CascadeType.DELETE_ORPHAN , que pode ser usada em conjunto com o JPA CascadeType.ALL .

Se você não planeja usar o Hibernate, terá primeiro que excluir explicitamente os elementos filho e, em seguida, excluir o registro principal para evitar registros órfãos.

seqüência de execução

  1. buscar a linha principal a ser excluída
  2. buscar elementos filho
  3. excluir todos os elementos filhos
  4. excluir linha principal
  5. Fechar session

Com o JPA 2.0, agora você pode usar a opção orphanRemoval = true

 @OneToMany(mappedBy="foo", orphanRemoval=true) 

Se você estiver usando o JPA 2.0, agora poderá usar o atributo orphanRemoval=true da anotação @xxxToMany para remover os órfãos.

Na verdade, o CascadeType.DELETE_ORPHAN foi descontinuado na CascadeType.DELETE_ORPHAN 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 o JPA com o EclipseLink, será necessário definir a anotação @PrivateOwned .

Documentação: Wiki do Eclipse – Usando Extensões JPA do EclipseLink – Capítulo 1.4 Como Usar a Anotação @PrivateOwned

você pode usar @PrivateOwned para excluir órfãos, por exemplo

 @OneToMany(mappedBy = "masterData", cascade = { CascadeType.ALL }) @PrivateOwned private List dataList; 

De acordo com o Java Persistence com o Hibernate , a exclusão órfã em cascata não está disponível como uma anotação do JPA.

Também não é suportado em XML JPA.

Acabei de encontrar esta solução, mas no meu caso não funciona:

 @OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = true não tem efeito.

Apenas @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) .

Remova targetEntity = MyClass.class , é ótimo.

Eu tive o mesmo problema e me perguntei por que essa condição abaixo não excluía os órfãos. A lista de pratos não foi apagada no Hibernate (5.0.3.Final) quando executei uma consulta de exclusão nomeada:

 @OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true) private List dishes = new ArrayList<>(); 

Então me lembrei que não devo usar uma consulta de exclusão nomeada , mas o EntityManager. Como eu usei o método EntityManager.find(...) para buscar a entidade e, em seguida, EntityManager.remove(...) para excluí-lo, os pratos foram excluídos também.

Para os registros, no OpenJPA antes do JPA2, era @ElementDependant.

Eu estava usando o mapeamento de um para um, mas a criança não estava sendo excluída A JPA estava dando violação de chave estrangeira

Depois de usar orphanRemoval = true, o problema foi resolvido