Hibernate: Löschen nur bei CascadingType.ALL möglich

daniel_sun

Erfahrenes Mitglied
Hallo,

ich habe ein Entity mit dem ich einen Tree aufspannen kann:

Java:
@Entity
public class Category{
	
        @Id @GeneratedValue
	private long id;
	private String name;
	private int type;
	@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinTable(
			   name = "Category_Childs", 
			   joinColumns = @JoinColumn(name = "category_id"), 
			   inverseJoinColumns = @JoinColumn(name = "child_id")
			)
	private Category parent;

	@OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
	private List<Category> childCategory = new ArrayList<Category>();

Ein Solcher Baum sieht z.B. so aus:

Code:
Node A
 |
 --Node A1
 |
 --Node A2

Num möchte ich Node A1 löschen. Folgende Funktion nutze ich dafür:

Java:
    public void deleteObject(Object o){

    	EntityTransaction tx = em.getTransaction();
    	tx.begin();
    	em.remove(o);
    	tx.commit();
    }

Mein Problem:
Die Node A1 wird nicht gelöscht. Ich bekomme aber auch keinen Fehler oder überhaupt irgendeine Consolenausgabe von Hibernate zu dem remove (Consolen ausgaben an sich sind natürlich eingestellt). Allerdings wird die funktion deleteObject aufgerufen und im Object o wird die richtige Node übergeben. Stelle ich nun bei der Variable parent von @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) auf @ManyToOne(cascade = CascadeType.ALL) funktioniert das löschen.

Natürlich wird nun die komplette Tree gelöscht da alle Parents und deren Childs gelöscht werden.

Wo liegt das Problem? Wie muss ich die Annotationen richtig setzen damit die Node inklusive ihrer Childs aber NICHT der parent gelöscht wird? Finde in dem Code den fehler nicht.

Gruß
Daniel_Sun
 
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) auf @ManyToOne(cascade = CascadeType.ALL) funktioniert das löschen.

Hier fehlt das CascadeType.Remove... Aber

Code:
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(
               name = "Category_Childs", 
               joinColumns = @JoinColumn(name = "category_id"), 
               inverseJoinColumns = @JoinColumn(name = "child_id")
            )
    private Category parent;
 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
    private List<Category> childCategory = new ArrayList<Category>();

Das sieht falsch aus. Ein Cascade ist auf jeden Fall zu viel, denn: Du deklarierst schon den CascadeType vom parent (ManyToOne) und deklarierst einen weiteren bei den childs (OneToMany) sagst dort aber diese Liste ist gemappt vom parent (mappedBy). Lass den Cascade von dem OneToMany weg und beim parent machst du CascadeType.All. Versuchs damit mal.
 
Zuletzt bearbeitet:
Zurück