Domanda

Sto riscontrando problemi nell'eliminazione dei nodi orfani utilizzando JPA con il seguente mapping

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

Sto riscontrando il problema dei ruoli orfani in giro per il database.

Posso usare l'annotazione org.hibernate.annotations.Cascade Hibernate tag specifico ma ovviamente non voglio legare la mia soluzione in un'implementazione Hibernate.

MODIFICA : sembra che JPA 2.0 includerà il supporto per questo.

È stato utile?

Soluzione

Se lo stai usando con Hibernate, dovrai definire esplicitamente l'annotazione CascadeType.DELETE_ORPHAN , che può essere usata in congiunzione con JPA CascadeType.ALL .

Se non prevedi di utilizzare Hibernate, dovrai prima eliminare esplicitamente gli elementi figlio e quindi eliminare il record principale per evitare qualsiasi record orfano.

sequenza di esecuzione

  1. recupera la riga principale da eliminare
  2. recupera elementi figlio
  3. elimina tutti gli elementi figlio
  4. elimina riga principale
  5. chiudi sessione

Con JPA 2.0, ora puoi utilizzare l'opzione orphanRemoval = true

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

Altri suggerimenti

Se si utilizza JPA 2.0, ora è possibile utilizzare l'attributo orphanRemoval = true dell'annotazione @xxxToMany per rimuovere gli orfani.

In realtà, CascadeType.DELETE_ORPHAN è stato deprecato in 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 si utilizza JPA con EclipseLink, è necessario impostare l'annotazione @PrivateOwned .

Documentazione: Wiki Eclipse - Utilizzo delle estensioni JPA EclipseLink - Capitolo 1.4 Come utilizzare l'annotazione @PrivateOwned

puoi usare @PrivateOwned per eliminare gli orfani per esempio

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

Secondo Java Persistence with Hibernate , eliminazione a cascata dell'orfano non è disponibile come annotazione JPA.

Inoltre, non è supportato in XML JPA.

Trovo questa soluzione ma nel mio caso non funziona:

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

orphanRemoval = true non ha alcun effetto.

Ho avuto lo stesso problema e mi chiedevo perché questa condizione di seguito non eliminasse gli orfani. L'elenco dei piatti non è stato eliminato in Hibernate (5.0.3.Final) quando ho eseguito una query di eliminazione denominata:

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

Quindi mi sono ricordato che non dovevo usare una query di eliminazione denominata , ma EntityManager. Dato che ho usato il metodo EntityManager.find (...) per recuperare l'entità e poi EntityManager.remove (...) per eliminarlo, i piatti sono stati eliminati come bene.

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

Rimuovi targetEntity = MyClass.class , funziona benissimo.

Per la cronaca, in OpenJPA prima di JPA2 era @ElementDependant.

Stavo usando il mapping uno a uno, ma il bambino non veniva cancellato L'APP stava violando la chiave esterna

Dopo aver utilizzato orphanRemoval = true, il problema è stato risolto

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top