# SQL Exception --> integrity constraint violation: unique constraint or index violatio



## roontafloor (13. November 2009)

Hallo zusammen

Ich bin dran ein DVD-Ausleihe Programm zu schreiben.
Zu erwähnen ist noch, das dies eine Semesteraufgabe für mein Studium ist und das folgendes Projekt übernommen werden musste, weil jeder in der Klasse von jemandem anders das Programm weiterentwickeln muss.


Jetzt habe ich ein Problem, wenn ich bei Punkt 2 (Film oder Schauspieler hinzufügen)einen Film der Datenbank hinzufügen möchte, kann ich zwar problemlos die verschiednene Parameter angeben (Filmname, Beschreibung usw.) doch nach Eingabe der Jahreszahl, nach welcher der Film der Datenbank hinzugefügt werden muss, bekomme ich folgende Fehlermeldung:


> Exception in thread "main" java.sql.SQLException: integrity constraint violation: unique constraint or index violation



Folgende Java-Klasse verwende ich
die Mainklasse:

```
import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Mainclass {
	public static boolean cancel=false;		
	public static String zeile;
	public static BufferedReader ein = new BufferedReader(new InputStreamReader(System.in));
	
	
	//main klasse geändert 																									NEU
	public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException{
		
	
		startScreen();
	}
		
		//Aufteilung der Methoden                                                                                                  NEU
		public static void startScreen() throws IOException, SQLException, ClassNotFoundException{
			Statement st;
			ArrayList movies;
			st=connect();
			movies=execute_select(st);
		
		//Start screen	

		System.out.println("Willkommen. Viel Spass mit der Rainy Day Movie Database!");
		System.out.println("Sie haben folgende Möglichkeiten: ");
		System.out.println("0: Alle Filme anzeigen ");
		System.out.println("1: Einen Eintrag editieren ");
		System.out.println("2: Einen Film oder Schauspieler hinzufügen");
		System.out.println("3: Einen Film nach Namen oder nach Schauspieler suchen ");
		System.out.println("4: Die Filme sortieren");
		System.out.println("5: Einen Film oder Schauspieler löschen");
		System.out.println("9: Programm beenden");
		
		menuAuswahl(movies, st);
		}
		
		//neuerstellte methode 																													NEU
		public static void menuAuswahl(ArrayList movies, Statement st) throws IOException, SQLException, ClassNotFoundException {
		String menuRegex = "[0-9]";
		boolean menuInput = false;
		
		// ÄNDERUNG Die Eingabe im Hauptmenu wird geprüft ob sie wirklich den vorhanden Optionen (0,1,2,3,4,5,9) entspricht					NEU
			while (menuInput== false) { 	
				System.out.println("Wählen Sie die entsprechende Zahl");
				System.out.print("--> ");
				String menuOption = new Scanner(System.in).nextLine();
				Pattern p4 = Pattern.compile(menuRegex);
				Matcher m4 = p4.matcher(menuOption);
				menuInput = m4.matches();
		        char c2 = menuOption.length() == 0 ? ' ' : menuOption.toUpperCase().charAt(0);	
		        if (menuInput == false){
		        	System.out.println("Falsche Eingabe bitte nur eine einstellige zahl");
		        }
		        
		        // Option 0																													NEU
		        else if (menuOption.equals("0")){
		        	System.out.println("Alle diese Filme befinden sich in unserer Datenbank:\n");
					show(movies); //Methode show aufrufen				
					
					
					System.out.println("Möchten Sie nun tun?");
					System.out.println("A  = Zurück zum Hauptmenu");
					System.out.println("B  = Programm beenden");
					
					//Verschachtelung der Optionen die man nach der Auflistung aller Filme bekommt                                            NEU
					String subMenuOption = new Scanner(System.in).nextLine();
			        char c1 = subMenuOption.length() == 0 ? ' ' : subMenuOption.toUpperCase().charAt(0);	   
			        System.out.println("Möchten Sie nun tun?");
					System.out.println("A  = Zurück zum Hauptmenu");
					System.out.println("B  = Programm beenden");
			        switch(c1) {					
							case 'A':
								startScreen();
								break;
							case 'B':
								System.out.println("Auf Wiedersehen!");
								cancel=true; 
								break;				
					}
		        }
				
		        
		     // Option 1																													NEU
				else if(menuOption.equals("1")){
					System.out.println("noch nicht realisiert!!");
				}
		     // Option 2																													NEU
				else if(menuOption.equals("2")){
					System.out.println("Möchten Sie einen Schauspieler oder einen Film hinzufügen?");
					System.out.println("1 Film                    2 Schauspieler");
					String s3 = new Scanner(System.in).nextLine();
			        char c3 = s3.length() == 0 ? ' ' : s3.toUpperCase().charAt(0);	        
			        switch(c3) {
			        
			        case '1':
						insertMovie(movies, st);
						break;
					case '2':
						insertActor(movies, st);						
						break;
					default: 			        
			        }
				}
		     // Option 3																													NEU
				else if(menuOption.equals("3")){
					System.out.println("Nach was wollen sie suchen?");
					System.out.println("1 Schauspieler                 2 Name");
					zeile = ein.readLine();
					// Schauen ob nsch Schauspieler oder Name gesucht werden soll und je nach eingabe search methode anders aufrufen
					if (zeile.equals("2")){
						System.out.println("Wie heist der Film?");
						zeile = ein.readLine();
						search(movies,(String)zeile,1); 
					}else if (zeile.equals("1")){
						System.out.println("Welchen Schauspieler möchten sie?");
						zeile = ein.readLine();
						search(movies,zeile,2);
					} else System.out.println("ungültige eingabe");
				}
		     // Option 4																													NEU
				else if(menuOption.equals("4")){
					System.out.println("noch nicht realisiert!!");
				}
		     // Option 5																													NEU
				else if(menuOption.equals("5")){
					System.out.println("noch nicht realisiert!!");
				}
		     // Option 9																													NEU
				else if(menuOption.equals("9")){
					System.out.println("Auf Wiedersehen!");
					System.exit(0);
				}
			
			}
			}
		
		public static void insertMovie(ArrayList movies, Statement st)throws SQLException, IOException, ClassNotFoundException {
			
			Scanner inp = new Scanner(System.in);			
			String fname;
			String fdescription;
			int rating1=0;
			int year1=0;
			int id=0;
			int aid=0;
			String rID ="";
			String ratingRegex = "[0-9]";
			String yearRegex = "[0-9]{4}";
			String actorRegex = "[0-9]";
			String yID = "";
			String aID = "";
			
			
			System.out.println("Geben Sie den Namen des Films an:");
			fname=inp.next();
			
			System.out.println("Geben Sie eine Beschreibung des Films ein:");
			fdescription=inp.next();
			
			
			// ÄNDERUNG, es können nun nur noch zahlen eingetippt werden    													NEU
			
			boolean rating = false;				
			while(rating == false) {
				System.out.println("Geben Sie eine Bewertung des Films ein( 1-10 ):");
				System.out.print("---> ");
				rID = new Scanner(System.in).nextLine();	
				Pattern p = Pattern.compile(ratingRegex);
				Matcher m = p.matcher(rID); 
				rating = m.matches();
					if(rating == false){
						System.out.println("Die Eingabe war Falsch");
					}											
			}
			// ÄNDERUNG es können nur noch 4 zahlen eingetippt werden											NEU		
			boolean year = false;
			while(year == false){
				System.out.println("Geben Sie ein wann der Film erstellt wurde:");	
				System.out.print("---> ");
				yID = new Scanner(System.in).nextLine();
				Pattern p1 = Pattern.compile(yearRegex);
				Matcher m1 = p1.matcher(yID);
				year = m1.matches();
				
					if(year == false){
						System.out.println("Die Eingabe war Falsch");
					}
				
			}
			id= movies.size()+1; 
			
			
			//film einfügen
			st.executeUpdate("INSERT INTO MOVIE VALUES ("+ id +", '"+ fname +"', '"+ fdescription + "'," + rID + ", " + yID +")");
			
			//ÄNDERUNGEN 	Die ID ist muss eine 3-stellige zahl sein													NEU
			boolean actor = false;
			while(actor == false){
				System.out.println("Geben sie die ID eines Schauspielers an:");	
				System.out.print("---> ");
				aID = new Scanner(System.in).nextLine();
				Pattern p2 = Pattern.compile(actorRegex);
				Matcher m2 = p2.matcher(aID);
				actor = m2.matches();
				
					if(actor == false){
						System.out.println("Die Eingabe war Falsch");
					}
				
			}
			
			st.executeUpdate("INSERT INTO MOVIE_ACTOR VALUES ("+ id +","+aID+" )"); //mit tabelle schauspieler verbinden
			
			// ÄNDERUNG  Die folgende nachricht erscheint und das program kehrt zum startbildschirm zurück								NEU
			System.out.println("Der Film wurde ins Archiv aufgenommen" + "\n");			
			startScreen();
		}
		
		public static void insertActor(ArrayList movies, Statement st)throws SQLException {
			
			Scanner inp = new Scanner(System.in);
			ResultSet rs;
			String fname;
			String fdescription;
			int rating=0;
			int year=0;
			int id=0;
			int aid=0;
			String aname;
			String aprename;
			
			rs= st.executeQuery("SET Schema RDMDB; SELECT * FROM Actor"); //zählen wie viele einträge
			while (rs.next())aid=aid+1;
			System.out.println("Vorname Schauspieler eingeben");
			aprename= inp.next();
			System.out.println("Nachname Schauspieler eingeben");
			aname=inp.next();
			aid=aid+1;
			st.executeUpdate("INSERT INTO ACTOR VALUES ("+aid+", '"+aname+"', '"+aprename+"')"); //einfügen schauspieler
			System.out.println("Geben sie die ID eines Filmes an wo er Mitspielt:");
			id=inp.nextInt();
			st.executeUpdate("SET Schema RDMDB; INSERT INTO MOVIE_ACTOR VALUES ("+ id +","+aid+" )"); //einfügen film wo er mitgemacht hat.
			
		}

		public static Statement connect() throws ClassNotFoundException, SQLException{

			// Diese Methode stellt die Verbindung zur datenbank her
			Class.forName("org.hsqldb.jdbcDriver"); //hsqldb treiber laden
			
			// Pfad zur datenbank angeben Achtung ändert sich auf jedem Computer, muss angepasst werden
			Connection con = DriverManager.getConnection("jdbc:hsqldb:file:C:\\Users\\kiran\\programme\\programmieren\\" +
					  "hsqldb\\data\\rainydays\\rainydays2");
			
			//SQL Select Statement Kreiren
			Statement st = con.createStatement();

			
				
			return st;
		}
		//Methode liest alle einträge aus db aus und speichert sie in einer array list
		public static ArrayList execute_select(Statement st) throws SQLException{
			int anz=0;
			int id=0;
			int idlast=1;
			String name="";
			String description="";
			int rating=0;
			int year=0;
			
			ArrayList movies= new ArrayList(); //arraylist movies erstellen
			ArrayList actors= new ArrayList();
			//SQL befehl ausführen
			ResultSet rs = st.executeQuery("SELECT Movie.movie_id, Movie.movie_name, Movie.movie_description," +
					" Movie.movie_rating, Movie.movie_year, Actor.actor_prename, Actor.actor_name FROM Movie, " +
					"Actor, movie_actor WHERE Movie.movie_id = movie_actor.movie_id AND Actor.actor_id= movie_actor.actor_id ;");
			// arraylist füllen
			while (rs.next()) {
				id=rs.getInt(1);
				
				if (id==idlast) //prüfen ob immer noch der gleiche film, wenn ja nur schauspieler hinzufügen, wenn nein Film.
					actors.add(new Actor (rs.getString(6) +" "+ rs.getString(7)));
			 
				else	{
					movies.add(new Movie(idlast,name,description ,rating , year,actors));
					actors.clear();
					actors.add(new Actor (rs.getString(6) +" "+ rs.getString(7)));
					}
				idlast=id;	
				name=rs.getString(2);
				description=rs.getString(3);
				rating=rs.getInt(4);
				year=rs.getInt(5);
				
				if(rs.isLast())movies.add(new Movie(idlast,name,description ,rating , year,actors)); //wenn letzter eintrag film hinzufügen
				
			}

			anz=anz+1;
			
			return movies;
			
		}
		
		//Methode zeigt alle filme auf Bildschirm an
		public static void show(ArrayList movies) {
			
			int anz=movies.size();
			// bis ans ende der arraylist jeden film ausgeben
			for (int i=0; i<anz;i++) {
				 Movie k=(Movie) movies.get(i);
				 k.print();
				 System.out.println("\n************************************************");
			}
			
			
		}
		//Methode sucht nach filname oder Schauspielern die Mitgemacht haben.
		public static void search(ArrayList movies, String name, int typ){
			int anz=movies.size();
			boolean found =false;
			ArrayList actors=new ArrayList();
			int actor_nr=0;
			//wenn suchen nach name
			if (typ==1){
				for (int i=0; i<anz;i++) { //list durchgehen bis gefunden wenn gefunden true sonst bleibt false
					 Movie k=(Movie) movies.get(i);
					 if (k.movie_name.equals(name)) {
						 System.out.println("\n************************************************");
						 k.print(); 
						 System.out.println("\n************************************************");
						 found =true;
						 break;
					 }
				}	 
			} else { //sonst
				for (int i=0; i<anz;i++) { //alle filme durchgehen
					Movie k=(Movie) movies.get(i);
					actors=k.movie_actor;
					actor_nr=actors.size();
					for (int j=0; j<actor_nr;j++) { //die schauspiler des films durchgehen wennn gesuchter dabei film ausgebe.
						Actor l=(Actor) actors.get(j);
						 if (l.actor_name.equals(name)) {
							 System.out.println("\n************************************************");
							 k.print(); 
							 System.out.println("\n************************************************");
							 found =true;
						 }
					}
				}
			}
			if (found==false)	System.out.println("kein eintrag gefunden"); //wenn nichts gefunden diese meldung
		}
		//Methode fügt filme und schauspileer der DB hinzu
	
		
}
```


Actor-Klasse:


```
^public class Actor { //Klasse autor Speichert die Autoren als objekt
	String actor_name;
	
	public Actor(String name){
		actor_name=name;
		
	}
	
	// geändert                                                                                   NEU
	public void print(){ //Methode druckt den Autor aus
		System.out.println(actor_name);
	}
}
```

Movie-Klasse


```
import java.util.*;

public class Movie { // Speichert die Filme als Objekt
	int movie_id;
	String movie_name;
	String movie_description; 
	int movie_rating;
	int movie_year;
	ArrayList movie_actor;
	//Actor movie_actor;
	
	public Movie(int id, String name, String description, int rating, int year, ArrayList actor) { //Konstruktor für objekt 
	//public Movie(int id, String name, String description, int rating, int year, Actor actor) {
		movie_id=id;
		movie_name=name;
		movie_description=description;
		movie_rating=rating;
		movie_year=year;
		movie_actor=(ArrayList) actor.clone();
	
	}
	public void print(){ //Gibt wertr des Objekts aus.
		
		//änderungen vorgenommen, Anzeige der Film auflistung                                                 NEU
		System.out.println("MovieID:     " + movie_id);
		System.out.println("Movie:       " + movie_name);
		System.out.println("Description: " + movie_description);
		System.out.println("Rating:      " + movie_rating);
		System.out.println("Year:        " + movie_year);
		
		
		int anz= movie_actor.size();
		for (int i=0; anz>i;i++) {
			 Actor k=(Actor) movie_actor.get(i);
			 // andere ausgabe                                                                                  NEU
			 System.out.print("Actor:       "); 
			 k.print();
		
			
		}
	}
	


	/*public static Movie view(){
		return null;
	}*/

}
```


Hier noch die Datenbank informationen:

Create-Statements:




> CREATE TABLE MOVIE (movie_ID INT PRIMARY KEY,
> movie_name CHAR(30),
> movie_description CHAR(30),
> movie_rating INT,
> ...




Insert-Statements:



> INSERT INTO MOVIE VALUES (1, 'TEST', 'TEST', 2, 1988)
> INSERT INTO MOVIE VALUES (2, 'American Gangster', 'gangster movie', 5, 2008)
> INSERT INTO MOVIE VALUES (3, 'The departed', 'mafia movie', 1, 2011)
> INSERT INTO MOVIE VALUES (4, '2012', 'catastrophe movie', 5, 2012)
> ...


----------



## Vereth (13. November 2009)

1. Du verwendest für die Film-ID movies.length+1.
Wenn du einen Film zwischendrin löschst, z.B. Film 2 von 8, wird die Id 8 beim nächsten Eintrag ein zweites Mal vergeben. Um das zu umgehen könntest du z.B. AutoIncrements in der Datenbank verwenden oder per Zufallszahlengenerator eine ID ausürfeln; wenn du dann wieder diese Exception hast, kannst du im catch-Zweig einen neuen Versuch mit einer neuen ID starten.

2. Dein Programm ruft startScreen() auf
, startScreen() ruft menuAuswahl() auf
, menuAuswahl() ruft insertMovie() auf
, insertMovie() ruft startScreen() auf => unendliche Schachtelungstiefe.
insertActor() macht den Fehler nicht.

Mache aus startScreen() eine reine Anzeigefunktion, die du in einer Eingabeschleife aufrufst z.B.


```
do
{ 
  movies = ...
  startScreen();
} while ( menuAuswahl(...) != 9 )
```


----------

