# Wie Abhängigkeit zu Elterntabelle lösen?



## at0m (26. Apr 2016)

Hallo zusammen,

ich versuche mein Problem anhand eines Klassendiagramms zu beschreiben:







Ich habe also drei Klassen; Auto, Sitz und Bezug. Ein Auto kann mehrere Sitze haben (OneToMany), ein Sitz aber nur einen Bezug (OneToOne).

Hier die Klasse Auto:


```
@NamedQuery(name="SelectAutos", query="Select a from Auto a")
@Entity
public class Auto implements Serializable {

    private static final long serialVersionUID = -555L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
   
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<Sitz> sitze;
   
    // Konstruktoren, Getter, Setter
}
```

Die Klasse Sitz:


```
@NamedQuery(name = "SelectSitze", query = "Select s from Sitz s")
@Entity
public class Sitz implements Serializable {

    private static final long serialVersionUID = 666L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @OneToOne(cascade = CascadeType.ALL)
    private Bezug bezug;

    // Konstruktoren, Getter, Setter
}
```

Und die Klasse Bezug:


```
@Entity
public class Bezug implements Serializable {

    private static final long serialVersionUID = 444L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String material;

    // Konstruktoren, Getter, Setter
}
```


Folgendermaßen erstelle ich ein neues Auto, in der Controller/Handler-Klasse AutoController (analog den Sitz):

```
public String newAuto() {
    autoCurrent = new Auto();
    return "autos_uebersicht?faces-redirect=true";
}
```

Das Auto speichere ich wie folgt:


```
public String saveAuto() {
    try {
        utx.begin();
        autoCurrent = em.merge(autoCurrent);
        em.persist(autoCurrent);
        autoList.setWrappedData(em.createNamedQuery("SelectAutos").getResultList());
        utx.commit();
    } catch (NotSupportedException e) {
        e.printStackTrace();
    } catch (SystemException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (RollbackException e) {
        e.printStackTrace();
    } catch (HeuristicMixedException e) {
        e.printStackTrace();
    } catch (HeuristicRollbackException e) {
        e.printStackTrace();
    }
    return "autos_uebersicht?faces-redirect=true";
}
```

Den Sitz speichere ich folgendermaßen:


```
public String saveSitz() {
    this.autoCurrent.getSitze().add(sitzCurrent);
    try {
        utx.begin();
        autoCurrent = em.merge(autoCurrent);
        em.persist(autoCurrent);
        autoList.setWrappedData(em.createNamedQuery("SelectAutos").getResultList());
        utx.commit();
    } catch (NotSupportedException e) {
        e.printStackTrace();
    } catch (SystemException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (RollbackException e) {
        e.printStackTrace();
    } catch (HeuristicMixedException e) {
        e.printStackTrace();
    } catch (HeuristicRollbackException e) {
        e.printStackTrace();
    }
    return "autos_uebersicht?faces-redirect=true";
}
```

Das Löschen des Autos funktioniert (auch, wenn diese Sitze und diese wiederum einen Bezug enthalten) wie folgt:


```
public String deleteAuto() {
    try {
        utx.begin();
    } catch (NotSupportedException e) {
        e.printStackTrace();
    } catch (SystemException e) {
        e.printStackTrace();
    }
    autoCurrent = autosList.getRowData();
    autoCurrent = em.merge(autoCurrent);
    em.remove(autoCurrent);
    autosList.setWrappedData(em.createNamedQuery("SelectAutos").getResultList());
    try {
        utx.commit();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (RollbackException e) {
        e.printStackTrace();
    } catch (HeuristicMixedException e) {
        e.printStackTrace();
    } catch (HeuristicRollbackException e) {
        e.printStackTrace();
    } catch (SystemException e) {
        e.printStackTrace();
    }
    return "autos_uebersicht?faes-redirect=true";
}
```

Das Problem kommt jetzt! Nämlich, wenn ich versuche einen Sitz zu löschen:


```
public String deleteSitz() {
    try {
        utx.begin();
    } catch (NotSupportedException e) {
        e.printStackTrace();
    } catch (SystemException e) {
        e.printStackTrace();
    }
    sitzCurrent = sitzList.getRowData();
    sitzCurrent = em.merge(sitzCurrent);
    em.remove(sitzCurrent);
    sitzList.setWrappedData(em.createNamedQuery("SelectSitze").getResultList());
    try {
        utx.commit();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (RollbackException e) {
        e.printStackTrace();
    } catch (HeuristicMixedException e) {
        e.printStackTrace();
    } catch (HeuristicRollbackException e) {
        e.printStackTrace();
    } catch (SystemException e) {
        e.printStackTrace();
    }
    return "sitze_uebersicht?faces-redirect=true";
}
```

Wenn ich versuche einen Sitz zu löschen, der zwangsläufig ein Teil des Autos ist (Fremdschlüssel von Auto verweist auf den Primärschlüssel des Sitzes), welcher wiederum einen Bezug enthält, dann bekomme ich die folgende Fehlermeldung:


```
Caused by: org.h2.jdbc.JdbcSQLException: Referentielle Integrität verletzt: "FK_DW0025YHI9UYOL04FFU8OR0JY: PUBLIC.AUTO_SITZ FOREIGN KEY(SITZS_ID) REFERENCES PUBLIC.SITZ(ID) (3)"
Referential integrity constraint violation: "FK_DW0025YHI9UYOL04FFU8OR0JY: PUBLIC.AUTO_SITZ FOREIGN KEY(SITZS_ID) REFERENCES PUBLIC.SITZ(ID) (3)"; SQL statement:
delete from Sitz where id=? [23503-173]
```

Es wird also die Referentielle Integrität verletzt. Ich habe versucht die @OneTo...-Annotationen um _orphanRemoval = true _zu ergänzen, damit die Einträge in den Abhängigkeitstabellen ebenfalls entfernt werden, doch leider hat es nichts gebracht.

Wie kann ich einen einzelnen Sitz des Autos löschen, inkl. dem Entfernen des Bezugs?

Würde mich sehr freuen, wenn jemand helfen könnte.


----------



## mrBrown (26. Apr 2016)

Ist die JoinTable nötig?

Wenn nein, kann man daraus eine bi-direktionele Beziehung mit FK zum Auto innerhalb der Sitze-Tabelle machen, das dürfte das Problem lösen.


----------



## at0m (27. Apr 2016)

Tatsächlich, ich konnte das Problem dadurch lösen. Vielen Dank!


----------

