# Db4o Delete Problem



## kjube (11. Mai 2012)

Hey...
Ich hab ne Klasse Spieler mit String foo und String foo2. foo ist quasi Primärschlüssel, wenn der deleted wird, soll foo2 auch gelöscht werden. Irgendwie finde ich den Fehler allerdings nicht. Hoffe jemand kann mir helfen.


```
public class SpielerLoeschen {
	
	public void loeschen(String name){
		EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
		configuration.common().objectClass(Spieler.class).cascadeOnDelete(true);
		ObjectContainer db = Db4oEmbedded.openFile("C:/Test/test.yap");
		try {
			ObjectSet<Spieler> result = db.queryByExample(name);
			Spieler spieler = result.next();
			db.delete(spieler);
			
		} catch (DatabaseFileLockedException e) {
			System.out.println(e.getMessage());
		}
		finally{
			db.close();
		}
	}
}


public class loeschen {

	public static void main(String[] args) {
		String name = "Torres";
		SpielerLoeschen loescheSpieler = new SpielerLoeschen();
		loescheSpieler.loeschen(name);
	}
}
```



> Exception in thread "main" java.lang.IllegalStateException
> at com.db4o.foundation.Iterable4Adaptor.next(Iterable4Adaptor.java:35)
> at com.db4o.internal.query.result.StatefulQueryResult.next(StatefulQueryResult.java:48)
> at com.db4o.internal.query.ObjectSetFacade.next(ObjectSetFacade.java:64)
> ...


----------



## SlaterB (11. Mai 2012)

der Fehlermeldung nach wird das Programm schon beim next() beendet,
da es in der main-Methode beginnt und keine Schleifen vorhanden sind, 
kann es auch nicht an Nebenwirkungen durch ein vorheriges delete() im gleichen Programm geben,

würdest du die delete()-Zeile, die nie drankommt, löschen, müsste das Programm doch genauso zum Fehler laufen,
stimmts?

wenn dann also im ganzen Programm delete() keine Rolle spielt, was läßt dich vermuten dass es ein delete-Problem ist?
kann es sein dass 'Torres' einfach nicht vorhanden ist?


----------



## kjube (11. Mai 2012)

In der DB ist er.







Liegt also irgendwie an der Syntax: 


```
Spieler spieler = result.next();
```

Irgendwelche Ideen? Die Dokumentation von db4o ist aber auch n crap... :E


----------



## SlaterB (11. Mai 2012)

hast du je mit 
> db.queryByExample(String);
erfolgreich einen Spieler geladen?
wenn nicht ist es nochmal ziemlich gewagt gleichzeitig delete() einzubauen und sich zu wundern dass alles zusammen nicht geht

was passiert wenn du zwei Klassen hast und mal den Namen eines Spielers, mal eines z.B. Autos hast und beide laden willst,
ist allein über die Konfiguration festgelegt, dass queryByExample(String) im Moment gerade auf Spieler gehen soll?

allgemein kenne ich queryByExample() so, dass man als 'Example' auch ein Dummy-Spieler-Objekt mit gesetzten Namen übergibt,
dann weiß das Framework dadurch, dass es um die Spieler-Klasse geht und lädt alle Objekte mit gleichen Attributen,
also mit dem gesuchten Namen

das erste gefunden Beispiel
Object-Specific Activation
mit 
> db.QueryByExample(new SensorPanel(1));
unterstützt meine Vermutung (sonst hätte ich sie vor den Posten auch vielleicht geändert  )

ebenso die API
db4o - database for objects - documentation



> [..]
> queryByExample() creates an ObjectSet containing all objects in the ObjectContainer that match the passed template object.
> [..]
> Query Evaluation
> ...


----------



## kjube (11. Mai 2012)

Das ist nur sone Art TestCase für mich zum üben. Erstmal egal ob es 2 Torres gibt und ich mit delte beide lösche. Ich habe es mittlerweile hingekriegt, dass er Index 0 löscht, bin aber zu blöd den Dummy mit einem übergebenen String zu vergleichen.
Hilf mir SlaterB. ( :
Habe mit QBE schon andere Operationen hingekriegt, von daher war ich mir eigentlich sicher, alles richtig geladen zu haben.


----------



## SlaterB (11. Mai 2012)

ein Spieler-Objekt erzeugen und darin den Namen setzen, wie gesagt,
falls deine Frage ist wie du mit queryByExample() alle Torres laden kannst


----------



## kjube (11. Mai 2012)

Ich will alle Torres löschen...


----------



## pl4gu33 (11. Mai 2012)

dazu musst du bei DB4o aber erstmal alle Torres laden


----------



## kjube (11. Mai 2012)

Welch sinnvoller Beitrag.


----------



## pl4gu33 (11. Mai 2012)

sry ich wollte ihn noch editieren ich hab dir gerade nen Beispiel schnell runterprogrammiert 
hoffe das reicht dir um es zu verstehen ? 


```
configuration.common().objectClass(Spieler.class).cascadeOnDelete(true);
```

brauchst du bei Strings nicht. Weil "only primitive and String members" werden mit der Default- Einstellung geupdatet / gelöscht

das bräuchtest du nur, wenn z.b. Spieler auf nen Objekt "Mannschaft" verweist und das dann auch gelöscht werden muss, oder geupdatet werden muss. 


```
import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.config.EmbeddedConfiguration;
import com.db4o.ext.DatabaseFileLockedException;

public class SpielerConf {
	
	public static void erstellen(ObjectContainer db,String name){
		db.store(new Spieler(name));
	}
	
	public static void read(ObjectContainer db){
		ObjectSet<Spieler> result = db.queryByExample(new Spieler(null));
        for(int i=0;i<result.size();i++){        	
        	System.out.println(result.get(i).getName());
        }
       
	}
    
    public static void loeschen(ObjectContainer db,String name){
		ObjectSet<Spieler> result = db.queryByExample(new Spieler(name));
        for(int i=0;i<result.size();i++){        	
        	db.delete(result.get(i));
        }
    }

    private static void deleteAll(ObjectContainer db) {
		// TODO Auto-generated method stub
    	ObjectSet<Spieler> result = db.queryByExample(new Object());
        for(int i=0;i<result.size();i++){        	
        	db.delete(result.get(i));
        }
	}
 

 
    public static void main(String[] args) {  
    	ObjectContainer db = null;
    	try {
         db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(),"test.yap");
    	 SpielerConf.erstellen(db, "Torres");
    	 SpielerConf.erstellen(db, "Gomez");
    	 SpielerConf.read(db);
    	 SpielerConf.loeschen(db,"Torres");
    	 SpielerConf.read(db);
    	 SpielerConf.deleteAll(db);
    	}catch(Exception e){
    		e.printStackTrace();
    	} finally{
              db.close();
        }
    }

	
}
```


```
public class Spieler {
	private String name;
	private int zahl;
	
	public Spieler(String n){
		name=n;
		zahl=100;
	}
	
	public String getName(){
		return name;
	}
	
	public int getZahl(){
		return zahl;
	}
	
	
}
```


----------



## kjube (11. Mai 2012)

Danke, genau sowas habe ich gebraucht. Ich poste mal lieber nicht den Rest meines Quellcodes... Hab deine Funktionen alle wesentlich umständlicher programmiert. ( :

Was genau macht: "db.queryByExample(new Spieler(null));"


----------



## pl4gu33 (11. Mai 2012)

kjube hat gesagt.:


> Danke, genau sowas habe ich gebraucht. Ich poste mal lieber nicht den Rest meines Quellcodes... Hab deine Funktionen alle wesentlich umständlicher programmiert. ( :
> 
> Was genau macht: "db.queryByExample(new Spieler(null));" und
> ObjectContainer db = null; (Main) ist quasi meine .yap datei?




ObjectContainer db = null; muss oben initalisiert sein, damit Finally die Variable auch kennt, kann man auch noch anders machen.



```
db.queryByExample(new Spieler(null))
```
  null ist in diesem Fall ein "Defaultwert" d.h. wenn man z.b. keinen Namen angeben möchte, und es werden dann alle Spieler ausgegeben


----------

