# Aktualisieren eine Tabelle mit OnetoMany-Beziehuung



## corofighter2 (2. Nov 2011)

Hallo,

ich habe folg. Problem. Ich habe zwei Relationen in einer Datenbank: User und Auto. Dabei handelt es sich um eine OnetoMany-Beziehung (ein User hat mehrere Autos). Ich habe nun mit dem Nebeans-Wizard eine JSF/JPA-Seite erstellt um diese zu editieren. Falls jmd. dies nicht kennen sollte. Netbeans erstellt folgendes:

- 2 Entities: Auto.java und User.java
- 2 ManagedBeans: UserController und AutoController
- 2 EJB: AutoFacade und Userfacade
- 1 AbstractFacade, die CRUD-Aktionen auf den o.g. Entitäten durchführt.

Natürlich möchte ich nun, dass jeder Nutzer nur seine Auto sehen kann, also habe ich UserController um folg. Methode erweitert:

```
public List<Auto> getAuto(){
return this.getFacade().find(this.getSelected().getId()).getAutoList();
}
```

Die Anzeige funktioniert auch soweit, jedoch wenn ich nun die Datenbank editiere, wird die Seite beim erneuten Laden nicht aktualisiert. Ich habe alles probiert, alle Scopes, alle Cascades, etc, nicht hilft.

Kann jemand helfen, Danke!


----------



## corofighter2 (2. Nov 2011)

Vielleicht zur Verdeutlichung. Jedesmal, wenn ich ein neues "Auto" einfüge, wird die Tabelle nicht aktualisiert.


----------



## JimPanse (3. Nov 2011)

Hi,

ich würde dein Design nochmal überdenken und eine Bi-direktionale Beziehung erstellen d.h


```
@Entity
public class User implements Serializable{

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
private List<Auto> autos;
}

public class Auto implements Serializable{

@ManyToOne(fetch = FetchType.LAZY)
private User user;
}
```

jetzt speicherst du jedes neues Auto direkt mit einer Referenz von dem Benutzer. Die Liste an Autos von einem Benutzer bekommst du einfach über einen join (in diesem Fall fetch join weil die Liste Lazy geladen werden soll)


```
from User t where join fetch t.autos where t.id =:userId
```
oder aus sicht eines Autos


```
from Auto t where t.user.id =:userId
```

Grüße


----------



## corofighter2 (3. Nov 2011)

Hallo,

vielen Dank für Deine Hilfe. Es war ja bereits eine bidirektionale Abbildung und mit Deinen SQL-Statements geht es jetzt auch. 

Da ich noch recht unerfahren mit JPA bin würde ich trotzdem gerne wissen, weshalb meine obige Lösung nur 1x nach Laden der Seite funktioniert und die find-Methode keine Änderung an der DB mitkriegt. Hier nochmals die find-Methode aus der AbstractFacade:

```
public T find(Object id) {
        
        return this.getEntityManager().find(entityClass, id);
    }
```

Die findAll()-Methode als Beispiel kriegt jede Änderung sofort mit:

```
public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }
```
Nochmals vielen Dank!!!


----------



## JimPanse (4. Nov 2011)

Hi,

ich kenne deinen Code nicht und das Verhalten ist nicht wirklich erklärbar d.h.

1. wird die find-methode() wirklich erneuert aufgerufen?

2. Welchen Scope hat deine ManagedBean? Wenn es SessionScope sein sollte könnte es auch daran liegen das der Aufruf nur ein einziges mal erfolgt. 


Grüße


----------



## corofighter2 (5. Nov 2011)

Nochmals danke.

zu 1: Ja, habe eine Zähler in die find()-Methode der AbstractFacade eingefügt. Der Aufruf erfolgt also.

zu 2: habe nochmals Session-, View und Request ausprobiert: keine Änderung. Kann es sein, dass die Standardeinstellung der Methode find(Object id) der Klasse EntityManager nur das einmalige Auslesen nach Starten der Applikation vorsieht und dass CRUD-Operationen in neue Listen/Collections durchgeführt werden müssen? Verwende EclipseLink.

Danke


----------



## JimPanse (8. Nov 2011)

corofighter2 hat gesagt.:


> zu 1: Ja, habe eine Zähler in die find()-Methode der AbstractFacade eingefügt. Der Aufruf erfolgt also.


Na hoffentlich nicht ;-) Dann könnte man eine Enität nur einmal laden...


corofighter2 hat gesagt.:


> zu 2: habe nochmals Session-, View und Request ausprobiert: keine Änderung. Kann es sein, dass die Standardeinstellung der Methode find(Object id) der Klasse EntityManager nur das einmalige Auslesen nach Starten der Applikation vorsieht und dass CRUD-Operationen in neue Listen/Collections durchgeführt werden müssen? Verwende EclipseLink.



Ok. Mit EclipseLink kenne ich mich nicht aus. Ich benutze wenn JPA+Hibernate entweder Plain oder mit EJB3 aber für mich hört es sich danach an dass der EntityManager deine Entität aus einer noch vorhanden Session lädt und nicht aus der Datenbank d.h. entweder mal flush() nach find() aufrufen oder
nochmal in der Doc nach lesen ob man expliziet die Session wieder freigeben muss.

Greetz


----------

