# Derby Datenbank speichert nicht



## LeoxD (17. Dez 2011)

Hi,

Ich bin gerade dabei mir ein Adressbuch zu schreiben und habe für die Datenhaltung Derby verwendet. Ich habe meine Fachklassen bereits fertig und versuche gerade erste Tests. In meiner main-funktion erstell ich einen neuen Kontakt, füge ihn über meinen Kontaktverwalter hinzu der ihn dann auch der Datenhaltung hinzufügt. Normalerweise müsste beim 2ten Start ein Fehler kommen, dass der Kontakt bereits in der DB ist, aber dies geschieht nicht. Kann mir einer von euch sagen warum?


```
package datenbank;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import Kontakt.Kontakt;

public class KontaktDAO {
	
	private static KontaktDAO dasKontaktDAO = new KontaktDAO();
	private Connection dbVerbindung;
	
	private KontaktDAO()
	{
		try
		{
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
			dbVerbindung = DriverManager.getConnection("jdbc:derby:Datenbank;");
			
			try
			{
				dbVerbindung.createStatement().executeUpdate("CREATE TABLE kontakte (" +
							"id INT NOT NULL," +
							"vorname VARCHAR(50) NOT NULL," +
							"nachname VARCHAR(50) NOT NULL," +
							"privadr VARCHAR(100) NOT NULL," +
							"privtel VARCHAR(50) NOT NULL," +
							"privmobil VARCHAR(50) NOT NULL," +
							"privfax VARCHAR(50) NOT NULL," +
							"geschadr VARCHAR(100) NOT NULL," +
							"geschtel VARCHAR(100) NOT NULL," +
							"geschfax VARCHAR(50) NOT NULL," +
							"PRIMARY KEY(id))");
			}
			catch (Exception ex)
			{
			}
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public static KontaktDAO getInstance()
	{
		return dasKontaktDAO;
	}
	
	public void create(Kontakt k)
	{
		try
		{
			PreparedStatement prepStatement = dbVerbindung.prepareStatement("INSERT INTO kontakte VALUES(?,?,?,?,?,?,?,?,?,?)");
			prepStatement.setInt(1, k.getId());
			prepStatement.setString(2, k.getVorname());
			prepStatement.setString(3, k.getNachname());
			prepStatement.setString(4, k.getPrivatAdresse());
			prepStatement.setString(5, k.getPrivatFestnetz());
			prepStatement.setString(6, k.getPrivatHandy());
			prepStatement.setString(7, k.getPrivatFax());
			prepStatement.setString(8, k.getGeschAdresse());
			prepStatement.setString(9, k.getGeschFestnetz());
			prepStatement.setString(10, k.getGeschFax());
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public Kontakt read(int id)
	{
		try
		{
			PreparedStatement prepStatement = dbVerbindung.prepareStatement("SELECT vorname, nachname, privadr, privtel, privmobil, privfax, geschadr, geschtel, geschfax FROM kontakte WHERE id = ?");
			prepStatement.setInt(1, id);
			ResultSet ergebnis = prepStatement.executeQuery();
			if (ergebnis.next())
			{
				Kontakt k = new Kontakt(id, ergebnis.getString(1), ergebnis.getString(2), ergebnis.getString(3), ergebnis.getString(4), ergebnis.getString(5), ergebnis.getString(6),
								ergebnis.getString(7), ergebnis.getString(8), ergebnis.getString(9));
				
				return k;
			}
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
		return null;
	}
	
	public void update(Kontakt k)
	{
		try
		{
			PreparedStatement prepStatement = dbVerbindung.prepareStatement("UPDATE kontakte SET vorname = ?, nachname = ?,"
																			+"privadr = ?, privtel = ?, privmobil = ?, privfax = ?,"
																			+"geschadr = ?, geschtel = ?, geschfax = ? WHERE id = ?");
			prepStatement.setInt(10, k.getId());
			prepStatement.setString(1, k.getVorname());
			prepStatement.setString(2, k.getNachname());
			prepStatement.setString(3, k.getPrivatAdresse());
			prepStatement.setString(4, k.getPrivatFestnetz());
			prepStatement.setString(5, k.getPrivatHandy());
			prepStatement.setString(6, k.getPrivatFax());
			prepStatement.setString(7, k.getGeschAdresse());
			prepStatement.setString(8, k.getGeschFestnetz());
			prepStatement.setString(9, k.getGeschFax());
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public void delete(Kontakt k)
	{
		try 
		{
			PreparedStatement prepStatement = dbVerbindung.prepareStatement("DELETE FROM kontakte WHERE id = ?");
			prepStatement.setInt(1, k.getId());
			prepStatement.executeUpdate();
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	public Iterator<Kontakt> ordneKontakteNachAlphabet()
	{
		try
		{
			ResultSet rs = dbVerbindung.createStatement().executeQuery("SELECT id FROM kontakte ORDER BY nachname DESC");
			List<Kontakt> kontaktlist = new ArrayList<Kontakt>();
			
			while (rs.next())
			{
				kontaktlist.add(read(rs.getInt(1)));
			}
			
			Iterator<Kontakt> kontaktirt= kontaktlist.iterator();
			
			return kontaktirt;
				
		}
		catch (Exception ex)
		{
			return null;
		}
	}
}
```


```
package Kontakt;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import datenbank.KontaktDAO;


public class Kontaktverwalter implements Observer{
	
	private HashMap<Integer, Kontakt> kontaktliste = new HashMap<Integer, Kontakt>();
	private KontaktDAO datenquelle = KontaktDAO.getInstance();
	private static Kontaktverwalter eineKontaktVerwaltung = new Kontaktverwalter();
	
	private Kontaktverwalter()
	{
	}
	
	public static Kontaktverwalter getInstance()
	{
		return eineKontaktVerwaltung;
	}
	
	public Kontakt finden(int id) throws KontaktException
	{
		Kontakt ergebnis = null;
		
		ergebnis = kontaktliste.get(id);
		if (ergebnis != null)
			return ergebnis;
		
		try
		{
			ergebnis = datenquelle.read(id);
			if (ergebnis != null)
				kontaktliste.put(id, ergebnis);
		}
		catch (Exception ex)
		{
			throw new KontaktException("Kontakt" + id + "konnte nicht gefunden werden");
		}
		return ergebnis;
	}
	
	public void hinzufuegen(Kontakt kontakt) throws KontaktException
	{
		int id = kontakt.getId();
		
		try
		{
			if ((kontaktliste.containsKey(id)) || (datenquelle.read(id) != null))
			{
					throw new KontaktException("Kontakt mit dieser Id ist schon vorhanden");
			}
			
			kontaktliste.put(kontakt.getId(), kontakt);
			datenquelle.create(kontakt);
			
			kontakt.addObserver(this);
		}
		catch (Exception ex)
		{
			throw new KontaktException("Kontakt "+id+" konnte nicht gespeichert werden");
		}
	}
	
	public void entfernen(Kontakt kontakt) throws KontaktException
	{
		kontaktliste.remove(kontakt.getId());
		
		try
		{
			datenquelle.delete(kontakt);
		}
		catch (Exception ex)
		{
			throw new KontaktException("Kontakt konnte nicht entfernt werden");
		}
	}
	
	public Vector<Kontakt> ordneKontakteNachAlphabet() throws KontaktException
	{
		try
		{
			Vector<Kontakt> ergebnis = new Vector<Kontakt>();
			Iterator<Kontakt> it = datenquelle.ordneKontakteNachAlphabet();
			
			while (it.hasNext())
			{
				ergebnis.add(it.next());
				kontaktliste.put(it.next().getId(), it.next());
			}
			return ergebnis;
		}
		catch (Exception ex)
		{
			throw new KontaktException("KontaktListe nicht aufrufbar");
		}
	}

	@Override
	public void update(Observable o, Object arg) 
	{
		Kontakt kontakt = (Kontakt) o;
		
		try
		{
			datenquelle.update(kontakt);
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
		
	}
}
```


```
package Logik;

import gui.KontaktGUI;

import javax.swing.SwingUtilities;

import Kontakt.Kontakt;
import Kontakt.KontaktException;
import Kontakt.Kontaktverwalter;

public class Adressbuch {

	public static void main(String[] args) 
	{
		Kontaktverwalter kv = Kontaktverwalter.getInstance();
		
		Kontakt test = new Kontakt(20, "Franz", "Busch", "test", "test", "test", "test","test","test","test");
		
		try {
			kv.hinzufuegen(test);
		} catch (KontaktException e) {
			System.out.println(e.getMessage());
		}
		
		
		
		SwingUtilities.invokeLater(new Runnable() 
		{
			public void run() 
			{
				KontaktGUI inst = new KontaktGUI();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}

}
```


----------



## Andgalf (18. Dez 2011)

Du fängst an einigen Stellen Exceptions und reagierst nicht darauf. (Silent Catch) zB. KontakDao Zeile 40 und 154 Das ist keine gute praxis, da Du eventuelle Fehler dadurch verdeckst. Du solltest an den Stellen mindestens eine Log-Ausgabe schreiben ... ich vermute, dass ein Fehler bei der DB-Connection o.ä auftritt den Du nicht mitbekommst.

[TIPP]Außerdem fängst Du die Exceptions sehr pauschal ... google mal nach java exceptions und antipattern[/TIPP]

P.S. Eine static variable vom KontaktDao im KontaktDao zu halten sieht auch ziemlich merkwürdig aus... was bezweckst Du damit?


----------



## LeoxD (19. Dez 2011)

Bezüglich deiner ersten Tipps Vielen Dank. Werd ich mir alles nochmal ganzgenau anschauen. Nun bezüglich der static Variable des KontaktDAO. Das ich in allen Klassen auf das selbe KontaktDAO Objekt zugreife und so wircklich nur eine Verbindung entsteht und es nur ein KontaktDAO Objekt gibt.


----------



## turtle (19. Dez 2011)

Ich bin mir sehr sicher, dass da keine Exception über den bereits vorhandenen Key gibt, weil bereits vorher eine Exception kommt, nämlich das die *Tabelle *schon existiert.

Diese aber gibst Du nicht und das ist gaaanz  :noe: schlechter Programmierstil, wie bereits angemerkt. 

Zumindestens solltest Du einen Stacktrace bei der Entwicklung ausgeben.


----------



## LeoxD (19. Dez 2011)

Ok, auch danke. Ich werde das ganze mit den Exception nochmal anschauen. Die Exception, dass es die Tabelle bereits gibt is gewollt! Da es bei Derby kein "CREATE IF NOT EXIST" gibt kann man das auch so lösen.


----------



## Andgalf (19. Dez 2011)

LeoxD hat gesagt.:


> Bezüglich deiner ersten Tipps Vielen Dank. Werd ich mir alles nochmal ganzgenau anschauen. Nun bezüglich der static Variable des KontaktDAO. Das ich in allen Klassen auf das selbe KontaktDAO Objekt zugreife und so wircklich nur eine Verbindung entsteht und es nur ein KontaktDAO Objekt gibt.



Ok, du willst dort einen Singleton haben, das verstehe ich. Aber warum ist dann der Kontaktverwalter auch ein Singleton?

Sauberer wäre es auch, wenn Du die DBConnection in einem Singleton kapselst und nicht das ganze DAO.

Mit Singletons sollte man sparsam umgehen. guck mal hier unter Nachteile:

http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)


----------



## turtle (19. Dez 2011)

> Da es bei Derby kein "CREATE IF NOT EXIST"



Das stimmt. Man kann aber auch über die conn.getMetaData() herausbekommen, ob die Tabelle bereits vorhanden ist ohne Exception-Trickserei.


----------



## LeoxD (19. Dez 2011)

Ja, das hatte ich am Anfang auch aber, es hatte nicht funktioniert und mir immer einen Error an den Kopf geworfen


----------



## LeoxD (19. Dez 2011)

Sorry, für den Doppelpost aber ich kann ja noch nicht editieren.
Also wegen dem Singleton, ich bin kein Javaprofi und arbeite gerade ein Buch durch dort wird beides als Singleton verwendet, da es ein Artikel,Lieferanten,Benutzer-Kunden Programm ist. Also entschuldigung fals das nicht so gut ist, aber so steht es nunmal dort.


----------



## Andgalf (20. Dez 2011)

LeoxD hat gesagt.:


> Also entschuldigung fals das nicht so gut ist, aber so steht es nunmal dort.



Also entschuldigen brauchst du dich dafür nicht. Wenn ich Kritik äußere, so hoffe ich dass diese immer konstruktiv verstanden wird.

Außerdem hätte es ja auch sein können, dass du dir dabei was gedacht hast und ich in dem Fall was lerne :rtfm:


----------

