# [JPA][EclipseLink] NullPointer bei begin()



## JavaNeuling1955 (2. Mai 2012)

Hallo Zusammen,

ich bin noch ein ziemlicher Neuling und komme einfach nicht weiter.

Was habe ich vor?

Ich möchte mir ein kleines Programm schreiben um meine Filme zu Verwalten. Dabei soll nicht merkbar eine Datenbank im Hintergrund laufen. 

Wie möchte ich es umsetzen?
Durch ein Tutorial, dass auch ohne Probleme bei mir lief, bin ich an EclipseLink und Apache Derby gekommen.
Im Programm selbst lebt ein ModelManager, der die Filme nach dem laden aus der Datenbank verwalten soll. Dazu soll er nicht nur eine Liste aller Filme, sondern auch eine Liste mit allen Personen enthalten.
Die Klassen Regisseur und Schauspieler erbt von der Klasse Person.

Film {String Titel, String Beschreibung, ..,Regisseur regisseur, List<Schauspieler> schauspieler,..}
Person {String vorname, String nachname,.., List<Film> filme,..}

Da auf Anhieb nichts geklappt hat, habe ich Person und Schauspieler raus geworfen und möchte nur die Regisseure speichern.

Jetzt aber zu meinem Fehler:


```
EntityManager theManager = getPersistence();
EntityTransaction et = theManager.getTransaction();
et.begin();
```


```
java.lang.NullPointerException
	at org.eclipse.persistence.internal.jpa.EntityManagerImpl.getActivePersistenceContext(EntityManagerImpl.java:1673)
	at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.begin(EntityTransactionImpl.java:49)
	at de.cl.testprojekt.controller.db.DatenbankDAO.speicherFilm(DatenbankDAO.java:50)
	at de.cl.testprojekt.controller.db.DatenbankDAO_test.kannDatenbankLaden(DatenbankDAO_test.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
```

Ich vermute, dass ich die Annotation bei den Entitys falsch gemacht habe.

Film:

```
@Entity
public class Film {
	@Id
	@GeneratedValue(strategy = GenerationType.TABLE)
	private long id;
	private String titel;
	private String genre;
	private String länge;
	private int Bewertung;
	
	@ManyToOne
	private Regisseur regisseur;
	
	private String nonsenseField = "";
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
.
.
.
.

	public Regisseur getRegisseur() {
		return regisseur;
	}
	public void setRegisseur(Regisseur regisseur) {
		this.regisseur = regisseur;
		regisseur.getFilme().add(this);
	}
	
	@Transient
	public String getNonsenseField() {
		return nonsenseField;
	}

	public void setNonsenseField(String nonsenseField) {
		this.nonsenseField = nonsenseField;
	}
	
}
```

Regisseur:

```
@Entity
public class Regisseur {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;
	private String vorname;
	private String nachname;
	@OneToMany(mappedBy = "regisseur")
	private List<Film> filme;
	
	private String nonsenseField = "";
	
	public Regisseur() {
		filme = new ArrayList<Film>();
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
.
.
.
.
	@Transient
	public String getNonsenseField() {
		return nonsenseField;
	}

	public void setNonsenseField(String nonsenseField) {
		this.nonsenseField = nonsenseField;
	}
	
}
```

persistence.xml
[XML]<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
	version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
	<persistence-unit name="datenbank" transaction-type="RESOURCE_LOCAL">


		<class>de.cl.testprojekt.model.Film</class>
		<class>de.cl.testprojekt.model.Regisseur</class>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
				<property name="javax.persistence.jdbc.url"
				value="jdbc:derby:datenbank;create=true" />
			<property name="javax.persistence.jdbc.user" value="test" />
			<property name="javax.persistence.jdbc.password" value="test" />

			<!-- EclipseLink should create the database schema automatically -->
			<property name="eclipselink.ddl-generation" value="create-tables" />
			<property name="eclipselink.ddl-generation.output-mode"
				value="database" />
		</properties>

	</persistence-unit>
</persistence>[/XML]


----------



## nillehammer (2. Mai 2012)

Ich glaube, dass das Deinen Fehler nicht beheben wird, aber trotzdem ein paar grundsätzliche Hinweise zu Deinen Entities:

Nimm statt primitives (long, int) lieber nullable Types, also die Wrapper (Long, Integer). Gerade bei der id ist das wichtig, weil z.B. an "id=null" erkannt wird, dass die Entity noch nicht in der Datenbank gesaved (also transient) ist.
Mische niemals Annotationen über gettern und über Feldern. Entscheide Dich für eins und ziehe es konsequent durch (in Deinem Fall verschiebe das _@Transient_ von _getNonsenseField_ hin zur entspr. Variablen).
Bei der Variablen _regisseur_ in der Klasse _Film_ fehlt meiner Meinung nach noch das _@JoinColumn_
Vermeide Sonderzeichen (also auch Umlaute) im Quellcode (hier bei der Variablen _länge_).


----------



## JavaNeuling1955 (2. Mai 2012)

Hallo und erstmal vielen Dank für deine Anmerkungen.

Ich habe sie natürlich alle sofort umgesetzt und kann deine Befürchtung leider bestätigen, dass Problem hat es nicht behoben.


----------



## nillehammer (2. Mai 2012)

```
at de.cl.testprojekt.controller.db.DatenbankDAO.speicherFilm(DatenbankDAO.java:50)
```
Kannst Du evtl. mal den Code von DatenbankDAO in Gänze posten oder mit korrekten Zeilennummern posten? Ich möchte mal rauskriegen, was genau hier null ist.


----------



## JavaNeuling1955 (2. Mai 2012)

Hallo,

Habe die Source Grade nicht mehr vorliegen..
Es passiert in der Zeile mit dem .begin() also in meinem Auszug oben in der dritten Zeile.
Weder der EntityManager noch EntityTransaction ist dabei Null.


----------



## nillehammer (2. Mai 2012)

Hmm, schwer zu sagen, was da jetzt genau null ist. Ich kann nur noch raten:

Ist Deine persistence.xml an der richtigen Stelle? Tipps siehe hier: Java How To ...: Where to put persistence.xml in web app?


----------



## JavaNeuling1955 (2. Mai 2012)

Hallo,

ja die persistence.xml befindet sich an der richtigen Stelle und wird auch korrekt eingelesen.
Es handelt sich übrigens um kein WebProjekt!

Komischerweise hat sich durch den JUnit Test (was anderes habe ich auch noch nicht) ein Eintrag in die Datenbank verirrt.. ohne das es ohne die NullPointer durchgelaufen ist..


----------



## JavaNeuling1955 (3. Mai 2012)

Hier noch einmal die komplette DatenbankDAO:


```
public class DatenbankDAO {
	
	private static Logger logger = Logger.getLogger(DatenbankDAO.class);
	private EntityManager myEntityManager;

	private synchronized EntityManager getPersistence() {
		if (myEntityManager == null) {
			EntityManagerFactory  factory = Persistence.createEntityManagerFactory("datenbank");
			myEntityManager = factory.createEntityManager();
		}
		return myEntityManager;
	};

	public List<Film> laden() {
		EntityManager theManager = getPersistence();
		Query queryDatenbank = theManager
				.createQuery("select f from Film f");
		List<Film> datenbank = queryDatenbank.getResultList();
		theManager.close();
		return datenbank;
	}
	
	public void speicherFilm(Film dn) {
		EntityManager theManager = getPersistence();
		EntityTransaction et = theManager.getTransaction();
		et.begin();
		theManager.merge(dn);
		et.commit();
		theManager.close();
	}
	
	public void speicherFilm(List<Film> filme) {
		EntityManager theManager = getPersistence();
		EntityTransaction et = theManager.getTransaction();
		et.begin();
		for(Film f: filme){
			theManager.merge(f);
		}
		et.commit();
		
		theManager.close();
	}
}
```

Ich hoffe mir kann hier jemanden helfen..


----------



## JavaNeuling1955 (3. Mai 2012)

Ich hänge hier nochmal meinen Test an..:


```
public void kannDatenbankLaden() throws Throwable {
		DatenbankDAO dau = new DatenbankDAO();
		List<Film> filme = dau.laden();
		Regisseur r = new Regisseur();
		r.setVorname("Dieter");
		r.setNachname("Müller");
		Film f = new Film();
		f.setTitel("Test Film");
		f.setGenre("ACTION");
		f.setBewertung(5);
		f.setDauer("90");
		f.setRegisseur(r);
		filme.add(f);
		dau.speicherFilm(filme);
		
		filme = dau.laden();
		for(Film f2:filme){
			System.out.println("Film "+f2.getId() + " " + f2.getTitel() + " mit Regisseur " + f2.getRegisseur().getVorname() + " "+ f2.getRegisseur().getNachname() + " in der Datenbank gefunden.");
			filme.remove(f2);
		}
		dau.speicherFilm(filme);
		
	}
```


----------



## JavaNeuling1955 (4. Mai 2012)

Hat hier niemand mehr eine Idee?

Eventuell ein Buchtipp oder ein gutes Tutorial? (das von Lars Vogel habe ich hier benutzt)


----------



## maki (4. Mai 2012)

Im Unitests gehts, sonst nicht?
Würde mal raten dass die persistence.xml nur vom Unit test gefundne wird.
Wo liegt die Datei denn?


----------



## JavaNeuling1955 (4. Mai 2012)

Nein der UnitTest geht *nicht*.
Ich habe auch noch keine Main-Methode sondern nur den Test, trotzdem befindet sich komischerweise ein Eintrag in der Datenbank.


----------



## nillehammer (7. Mai 2012)

Die Exceptions sind jetzt weg? Nur die Anwendung speichert die Daten nicht so wie gewollt? Schreib doch bitte mal genau was passiert und inwieweit das von Deinen Erwartungen abweicht. "Geht nicht und "Eintrag in Datenbank verirrt" ist etwas wenig Information für eine Fehleranalyse.


----------



## JavaNeuling1955 (7. Mai 2012)

Hallo,

habe die Model's und die Datenbankanbindung komplett überarbeitet und werde die Quelltexte heute Abend nochmal nachliefern.

Da ich das Programm grade nicht vorliegen habe kann ich die genaue Exception nicht nennen aber es klingt nach dieser hier:


```
java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'XXXX' defined on 'XXX'.
```


----------



## nillehammer (8. Mai 2012)

> habe die Model's und die Datenbankanbindung komplett überarbeitet und werde die Quelltexte heute Abend nochmal nachliefern.


Das *kann* helfen, wenn es jetzt ein neues Problem ist. Grundsätzlich schreibe aber bitte immer auch in Deutsch, was Du machen willst (erwartetes Verhalten) und was tatsächlich passiert (tatsächliches Verhalten). Java-Code ist zumindest keine gute Form der Klärung des ersteren, weil, wenn er das erwartete Verhalten erklären würde, würde er funktionieren. Und (ich wiederhole mich): ""Geht nicht und "Eintrag in Datenbank verirrt" ist etwas wenig Information für eine Fehleranalyse des tatsächlichen Verhaltens."


----------

