JTree rekursiv aus DB erzeugen

Kontar

Grünschnabel
Grüßt Euch,

im folgenden findet Ihr eine Methode von mir, welche dazu dienen soll einen JTree mit Informationen aus einer Datenbank zu erzeugen. Die Informationen liegen wie folgt vor

Code:
Artikel   1   Hauptmenü
Kunde     1   Hauptmenü
Firma     2   Hauptmenü
Angebot   1   Hauptmenü
Liste     1   Firma
Ansicht   1   Firma

Die Methode wird zunächst mit "Hauptmenü" und dem "root" aufgerufen, sollte die Markierung "2" auftauchen wird an dieser stelle neu mit der Programmgruppe selektiert.

Code:
public DefaultMutableTreeNode makeTree(String name, DefaultMutableTreeNode root) throws SQLException {
		
		Db datab = new Db();

		ResultSet rsTree = datab.selectSql(	"SELECT programm_name, kennzeichen, programm_menue FROM tbl_zugriff " +
											"WHERE programm_menue='" + name + "'");
		
		while(rsTree.next()) {
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(rsTree.getString("programm_name"));
			root.add(node);

			if(rsTree.getInt("kennzeichen")==2) {
				makeTree(rsTree.getString("programm_name"), node);
			}	
		}
		return root;
	}

erwartetes Ergebnis:

Code:
Hauptmenü
   |- Kunde
   |- Firma
      |- Liste
      |- Ansicht
   |- Angebot

tatsächliches Ergebnis:

Code:
Hauptmenü
   |- Kunde
   |- Firma
      |- Liste
      |- Ansicht

Beobachtung:

Nach Verlassen des rekursiven Aufrufs von der Methode makeTree sind keine Daten mehr im alten ResultSet rsTree vorhanden. Jene sollten aber vor dem Aufruf einer rekursiven Methode gespeichert werden um an der Stelle weiter zu machen, an der der aktuelle Methodenaufruf unterbrochen wurde.

Würde mich freuen wenn mir an dieser Stelle jemand weiterhelfen könnte.

Danke

Gruß

Kontar
 
Das liegt am Autocloseable. Ich zitiere mal unsere DOC :
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
Quelle : API-Doc java.sql.ResultSet
Frei übersetzt bedeutet es das ein ResultSet automatisch geschlossen / ungültig wird sobald sein zugehöriges Statement geschlossen wird , erneut ausgeführt wird , oder dazu benutzt wird um das nächste ResultSet zu erzeugen. Was also passiert ist nicht mehr als das der Zugriff auf das aktuelle ResultSet durch den rekursiven Aufruf auf das Statement von dem es kommt ungültig wird.

Es ist eh ein sehr schlechtes Design die Daten auf diese weise aus der Datenbank zu holen. Du solltest lieber alle Daten auf einmal in eine List oder ähnliches laden und dann damit arbeiten. Geignete Funktionen sollte man entsprechen erstellen können.
 
Natürlich wird das aktuelle ResultSet geschlossen sobald es unter dem gleichen Namen ein weiteres Mal aufgerufen wird. Ich schreibe aber nicht in das selbe Resultset sondern lege durch den erneuten Methodenaufruf ein neues ResultSet an, was zwar den gleichen Namen trägt aber eine andere ID hat.
 
Du hast das Prinzip von OOP und Autocloseable scheinbar nicht verstanden.
Es ist egal ob du in einem rekursiven Aufruf ein komplett neues ResultSet erzeugst oder nicht ... du verwendest jedoch dasselbe Statement um die Anfrage abzusetzen. Und laut Doc wird damit das ResultSet der höheren Ebene geschlossen wodurch Manipulationen , und sei es auch nur das Auslesen , ungültig werden.
 
Ich habe mir noch einmal die Datenbank-Klasse aus der Anwendung angeschaut, in der die ResultSets ihre Inhalte nicht verloren haben. Der Unterschied ist, dass dort für jedes ResultSet eine neue Connection erstellt wird. Wodurch diese Methode zumindest lauffähig wird.
 
Zuletzt bearbeitet:
Was aber weder im Sinne von OOP noch halbwegs schön oder gar sinnvoll ist. Klar funktioniert es wenn für jeden Aufruf eine komplett neue Verbindung , ein neues Statement und damit ein unabhängiges ResultSet verwendet wird ... aber man sollte sich wirklich überlegen ob dieser Overhead gerechtfertigt ist oder ob man sich nicht doch die Arbeit macht und sich mal Array , Listes und Collections ansieht.
 

Neue Beiträge

Zurück