2017-08-18 1 views
0

Ich kämpfe für eine Woche mit folgendem Problem:Spring Data JPA - ManyToOne nicht mehr Kind zu löschen, ohne übergeordnete Liste zu Modifizieren

Wie ist es möglich, ohne Änderung die Liste auf dem besitz ein Kind Entität durch ein Repository zu löschen (Elternteil) Seite der Beziehung?

Vielen Dank im Voraus.

Ich hoffe auf einige Antworten!

Die Kind Klasse:

@Entity 
@Table(name = "child") 
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class Child implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") 
    @SequenceGenerator(name = "sequenceGenerator") 
    private Long id; 

    @ManyToOne 
    private Parent parent; 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public Long getParent() { 
     return parent; 
    } 

    public void setParent(Parent parent) { 
     this.parent = parent; 
    } 
} 

Und die Eltern Klasse:

@Entity 
@Table(name = "parent") 
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class Parent implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator") 
    @SequenceGenerator(name = "sequenceGenerator") 
    private Long id; 

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) 
    @JsonIgnore 
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
    private Set<Child> children = new HashSet<>(); 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public Set<Child> getChildren() { 
     return children; 
    } 

    public void setChildren(Set<Child> children) { 
     this.children = children; 
    } 

    public Parent addChild(Child child) { 
     this.children.add(child); 
     child.setParent(this); 
     return this; 
    } 

    public Parent removeChild(Child child) { 
     this.children.remove(child); 
     child.setParent(null); 
     return this; 
    } 
} 

Und hier die Test:

@Test 
@Transactional 
public void testParentToChildRelationShip() { 
    Parent parent = new Parent(); 
    Child child = new Child(); 

    parent.addChild(child); 
    parent.addChild(new Child()); 
    parent.addChild(new Child()); 
    parent.addChild(new Child()); 

    parentRepository.save(parent); 

    Assertions.assertThat(parentRepository.count()).isEqualTo(1L); 
    Assertions.assertThat(childRepository.count()).isEqualTo(4L); 

    childRepository.delete(child); 


    Assertions.assertThat(parentRepository.count()).isEqualTo(1L); 
    // fails 
    Assertions.assertThat(childRepository.count()).isEqualTo(3L); 

    parentRepository.delete(parent.getId()); 

    Assertions.assertThat(parentRepository.count()).isEqualTo(0L); 
    Assertions.assertThat(childRepository.count()).isEqualTo(0L); 
} 

Der Test funktionieren würde, wenn ich ein, bevor das Kind zu löschen,

child.getParent().removeChild(child); 

aber ich möchte, ruft dies zu vermeiden. Gibt es eine Möglichkeit, die Methode Child-JPA-Repository.delete aufzurufen? Oder andere Anmerkungen, die ich verpasst habe?

+0

Was passiert, wenn man flush() nach childRepository.delete (Kind) nennen? –

+0

Es macht keinen Unterschied. Die Anzahl der untergeordneten Repositorys ist immer noch 4. Ich habe versucht, auf das untergeordnete Repository, auf das übergeordnete Repository und auf beide –

+0

zu spülen. Was passiert, wenn Sie den Satz von einer Setup-Methode auffüllen - ist der txn-Bereich anders? – farrellmr

Antwort

1

Seit child hat zusammen mit parent dieses Problem konfrontiert sind, müssen Sie die Verbindung zwischen Kind und Eltern entfernen entweder mit

parent.removeChild(child); 

oder

child.getParent().removeChild(child); 
0

Entfernen Sie diese Zeilen aus dem Elternklasse und auch Setzer und Getter von children

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) 
     @JsonIgnore 
     @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
     private Set<Child> children = new HashSet<>(); 

Ich glaube, Sie child mapping von Ihrem parent class entfernen können, so können Sie einfach das Kind Zeile löschen mit ChildRepositorydelete() Methode, aber Problem ist, dass Sie Ihr Kind zu retten manuallyChildRepositorysave() verwenden. Sie können das untergeordnete Objekt nicht mit dem übergeordneten Objekt unter ParentRepository speichern. Ändern Sie Ihre -Test Code wie unten für das Speichern child und parent

Parent parent = new Parent(); 
Parent parent = parentRepository.save(parent); 

    Child child = new Child(); 
    child.setParent(parent); 
    childRepository.save(child); 
+0

Gibt es keine andere bidirektionale Möglichkeit, dieses Problem zu lösen? –

+0

Ich denke, andere Lösung sollte sein, dass Sie ein Feld 'isDeleted' in Ihrer' Kindklasse' erstellen können und nicht versuchen, die untergeordnete Zeile zu löschen, nur dieses Feld 'isDeleted' auf' true' aktualisieren und zum Zeitpunkt des Erhaltens nur die Zeile, die 'isDeleted'' false' sind. – CIPHER007

Verwandte Themen