Vra

Ek het 'n probleem met 'n eenvoudige @OneToMany kartering tussen 'n ouer en 'n kind entiteit.Alles werk goed, net dat kinderrekords nie uitgevee word wanneer ek dit uit die versameling verwyder nie.

Die ouer:

@Entity
public class Parent {
    @Id
    @Column(name = "ID")
    private Long id;

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "parent")
    private Set<Child> childs = new HashSet<Child>();

 ...
}

Die kind:

@Entity
public class Child {
    @Id
    @Column(name = "ID")
    private Long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="PARENTID", nullable = false)
    private Parent parent;

  ...
}

As ek nou delete en kind uit die childs Set, word dit nie van die databasis verwyder nie.Ek het probeer om die nietig te maak child.parent verwysing, maar dit het ook nie gewerk nie.

Die entiteite word in 'n webtoepassing gebruik, die uitvee vind plaas as deel van 'n Ajax-versoek.Ek het nie 'n lys van verwyderde kinders wanneer die stoor-knoppie gedruk word nie, so ek kan hulle nie implisiet uitvee nie.

Was dit nuttig?

Oplossing

JPA se gedrag is korrek (betekenis volgens die spesifikasie):voorwerpe word nie uitgevee bloot omdat jy dit uit 'n OneToMany-versameling verwyder het nie.Daar is verskaffer-spesifieke uitbreidings wat dit doen, maar inheemse JPA maak nie voorsiening daarvoor nie.

Dit is deels omdat JPA nie eintlik weet of dit iets wat uit die versameling verwyder is, moet verwyder nie.In terme van objekmodellering is dit die verskil tussen samestelling en "aggregasie*.

In samestelling, die kinderentiteit bestaan ​​geen bestaan ​​sonder die ouer nie.'n Klassieke voorbeeld is tussen Huis en Kamer.Verwyder die huis en die kamers gaan ook.

Aggregasie is 'n losser soort assosiasie en word getipeer deur Kursus en Student.Vee die kursus uit en die student bestaan ​​steeds (waarskynlik in ander kursusse).

Jy moet dus óf verskaffer-spesifieke uitbreidings gebruik om hierdie gedrag af te dwing (indien beskikbaar) óf die kind uitdruklik uitvee EN dit uit die ouer se versameling verwyder.

Ek is bewus van:

Ander wenke

In bykomend tot Cletus 'antwoord, JPA 2.0 , finale sedert Desember 2010 , stel 'n orphanRemoval kenmerk op @OneToMany notas. sien hierdie blog inskrywing vir meer besonderhede.

Let daarop dat sedert die spec is relatief nuut, nie al JPA 1 verskaffer het 'n finale JPA 2 implementering. Byvoorbeeld, die Hibernate 3.5.0-Beta-2 vrylating nog hierdie kenmerk nie ondersteun.

Jy kan probeer om hierdie:

@OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true).

Soos verduidelik, is dit nie moontlik om te doen wat ek wil met JPA, so ek in diens van die hibernate.cascade body, met hierdie, die relevante kode in die Ouer klas lyk nou soos volg:

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parent")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.DELETE,
            org.hibernate.annotations.CascadeType.MERGE,
            org.hibernate.annotations.CascadeType.PERSIST,
            org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<Child> childs = new HashSet<Child>();

Ek kon nie eenvoudig gebruik "alle" as dit sou die ouer sowel geskrap.

Hier waterval, in die konteks van verwyder, beteken dat die kinders verwyder word as jy die ouer te verwyder. Nie die vereniging. As jy met behulp van Hibernate as jou JPA verskaffer, kan jy doen dit met behulp van hiberneer spesifieke waterval .

Jy kan probeer om hierdie:

@OneToOne(cascade = CascadeType.REFRESH) 

of

@OneToMany(cascade = CascadeType.REFRESH)
@Entity 
class Employee {
     @OneToOne(orphanRemoval=true)
     private Address address;
}

na href="https://stackoverflow.com/questions/18813341/what-is-the-difference-between-cascade-and-orphan-removal-from-db">.

scroll top