# JPA Cascade Types



## Andreas29 (27. Jul 2012)

Hi,

ich habe eine Frage zu den JPA CascadeTypes:
Ich habe zwei Entitäten, A und B. A hat eine Liste von Bs, diese ist mit @OneToMany(cascade = { CascadeType.ALL }, mappedBy = "b") annotiert. Wenn ich jetzt eine A Entität speichere, wird B mitgespeichert (sofern B nicht vorher schon explizit gespeichert wurde). Das ist wunderbar. Wenn ich jetzt die Annotation durch @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.DETACH }, mappedBy = "b") ersetze, werden die B-Entities nicht mehr mitgespeichert. Sprich, es scheint einen Unterschied zwischen dem CascacdeType.ALL und der Liste aller einzelnen CascadeTypes zu geben. Warum? Lt Dokumentation sollte dies nicht so sein. Kann mir das irgendwer erklären? Hat irgendwer ähnliche Erfahrungen gemacht?

Falls es von Interesse ist, im Hintergrund läuft eine Oracle 11 Datenbank und der Source wird über JUnit ausgeführt.

Grüße und schonmal schönes Wochenende sowie vielen Dank für die Hilfe,
Andreas


----------



## mvitz (27. Jul 2012)

Interessanter wäre hier wohl zu erfahren, welchen JPA Provider (Hibernate, EclipseLink, OpenJPA, ...) du einsetzt.


----------



## Andreas29 (27. Jul 2012)

Hi,

du hast recht, das hätte ich dazu schreiben können. 

Wird jetzt schnell nachgeholt:
Ich verwende Hibernate in Version 3.6.5.FINAL

Grüße,
Andreas


----------



## nillehammer (27. Jul 2012)

Vielleicht ist es nur ein Schreibfehler, aber

```
@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "b")
```
Heißt, dass es in B eine Variable(ggf. inkl Getter) des Typs A geben muss, die komischerweise "b" heißt (oder der Getter getB()). Wenn es das in A so nicht gibt, würde ich eigentlich erwarten, dass das Mapping von vorn herein abgewiesen wird. Aber vielleicht ist Hibernate da gnädig und kommt dann am Ende durcheinander. Alles aber leider nur Spekulation, weil ich hier kein JPA-Projekt mit Hibernate zum testen habe.


----------



## mvitz (27. Jul 2012)

Folgendes Beispiel macht bei mir keine Probleme:

```
package de.mvitz.example.hibernate.entities;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class A {

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(cascade = { CascadeType.PERSIST }, mappedBy = "a")
    private List<B> bs;

    public Long getId() {
        return id;
    }

    public List<B> getBs() {
        return bs;
    }

    public void setBs(List<B> bs) {
        this.bs = bs;
        for (B b : bs) {
            b.a = this;
        }
    }

    @Override
    public String toString() {
        return "A[" + id + ", " + bs + "]";
    }

}
```


```
package de.mvitz.example.hibernate.entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class B {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    A a;

    public Long getId() {
        return id;
    }

    @Override
    public String toString() {
        return "B[" + id + "]";
    }

}
```


```
package de.mvitz.example.hibernate;

import java.util.Arrays;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;

import de.mvitz.example.hibernate.entities.A;
import de.mvitz.example.hibernate.entities.B;

public class Main {

    public static void main(String[] args) {
        final EntityManager em = Persistence.createEntityManagerFactory("test").createEntityManager();
        
        List<A> as = em.createQuery("SELECT a FROM A a", A.class).getResultList();
        for (A a : as) {
            System.out.println(a);
        }
        System.out.println("=====");

        A a = new A();
        a.setBs(Arrays.asList(new B(), new B(), new B()));
        System.out.println(a);

        em.getTransaction().begin();
        em.persist(a);
        em.getTransaction().commit();

        System.out.println("=====");
        as = em.createQuery("SELECT a FROM A a", A.class).getResultList();
        for (A anA : as) {
            System.out.println(anA);
        }

        em.close();
    }

}
```
[XML]<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
        <class>de.mvitz.example.hibernate.entities.A</class>
        <class>de.mvitz.example.hibernate.entities.B</class>
        <properties>
            <property name="javax.persistence.jdbc.driver"   value="org.h2.Driver"     />
            <property name="javax.persistence.jdbc.url"      value="jdbc:h2:mem:" />
            <property name="javax.persistence.jdbc.user"     value="admin"             />
            <property name="javax.persistence.jdbc.password" value="test"              />

            <property name="hibernate.hbm2ddl.auto"          value="create-drop"       />
        </properties>
    </persistence-unit>
</persistence>[/XML]


----------

