GambaJo:1. Kann man list.clear() und list.addAll() in einer Transaktion durchführen, oder muss ich nach list.clear() das Rezept erst speichern und dann die Liste füllen?
Das hängt etwas von deinem Transaktionsbegriff ab: natürlich ist clear()/addAll() keine atomare Operation, aber das Ersetzen der ArrayList durch eine andere ja auch nicht, von daher sehe ich da erstmal kein "transaktionelles" Problem.
Hier mal ein Beispiel, wie das Beispiel von oben geändert werden müsste:
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.db4o.Db4o;
import com.db4o.ObjectContainer;
class Rezept {
private List<Zutat> zutaten = new ArrayList<Zutat>();
public void setZutaten(List<Zutat> zutaten) {
this.zutaten.clear();
this.zutaten.addAll(zutaten);
}
public String toString() {
return zutaten.toString();
}
}
class Zutat {
private String name;
public Zutat(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
public class RezeptDatenbank {
public static void main(String[] args) {
new File("test.yap").delete();
Db4o.configure().objectClass(Rezept.class).objectField("zutaten").cascadeOnUpdate(true);
// Alternativ, aber etwas "gröber":
// Db4o.configure().objectClass(Rezept.class).cascadeOnUpdate(true);
ObjectContainer db4o = Db4o.openFile("test.yap");
// Rezept speichern
Rezept rezept = new Rezept();
List<Zutat> zutaten = new ArrayList<Zutat>();
rezept.setZutaten(zutaten);
db4o.set(rezept);
db4o.commit();
// Zutatenliste 100 mal aktualisieren
Zutat salz = new Zutat("Salz");
Zutat zucker = new Zutat("Zucker");
for (int i = 0; i < 100; i++) {
zutaten = new ArrayList<Zutat>();
zutaten.add(zucker);
zutaten.add(salz);
rezept.setZutaten(zutaten);
db4o.set(rezept);
db4o.commit();
}
// Jetzt ist eine ArrayList in der Datenbank gespeichert...
System.out.println(db4o.get(List.class).size());
db4o.close();
// Zur Kontrolle einmal das Rezept ausgeben
db4o = Db4o.openFile("test.yap");
System.out.println(db4o.get(Rezept.class));
db4o.close();
}
}
GambaJo: 2. Wie kann ich das alte List-Objekt löschen?
db4o.delete(dasAlteListObject);
Das kann allerdings etwas "tricky" werden, wenn man eine saubere Trennung der Domain-Klassen von der Persistenzschicht anstrebt, weil man ja die ArrayList aus der Rezept-Klasse (die ja eigentlich ein privates Geheimnis der Rezept-Klasse ist), ja irgendwie an die Datenbank rausreichen muss. In unserem Beispiel wäre das ja sogar halbwegs problemlos möglich, weil man sich ja über die getZutaten() die alte Liste vor dem setZutaten() holen könnte, um so anschließend in der Datenbank zu löschen.
Grüße, Maik
http://db4o.blogspot.com/