# BEGIN, COMMIT, EntityManager



## CroweHammer (5. Feb 2010)

Morgen Forum,

ich muss mich heute mal auf euer Wissen beziehen. 
Ich versuch mittels einem Insert Into Befehl Daten in meine SQL-Datenbank zu schreiben und diesen Vorgang mittels einem BEGIN und COMMIT abzusichern.
Der entsprechende Code sieht folgendermaßen aus:

```
EntityManagerFactory emf = null;
EntityManager em = emf.createEntityManager();
	try {
		em.getTransaction().begin();
			if (new LearnTable(this.connection, exercisearea).insert(connection)) {
				Helpers.debug("Table '%s' with language '%s' " +
						"successfully created!\n", exercisearea,
				((Language)cb_language.getSelectedItem()).getName());
			}
		em.getTransaction().commit();
	} catch(Exception e) {		
		e.printStackTrace();
		Messages.showError("Datenbankfehler");
		em.getTransaction().rollback();
	} finally {
		em.close();
	}
```
Meine dazugegehörige insert-Methode:

```
public boolean insert(DBConnection connection) {
		String query_insert_exercisearea =
			"insert into exercisearea(areaname) values('" + this.exercisearea + "')";
 
		if (connection.updateDB(query_insert_exercisearea) == 1) {
			return true;
		} else {
			return false;
		}
	}
```
Will ich dies jetzt ausführen bekomm ich immer ein NullPointerException. Siehe:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at gui.TablesFrame.btn_createActionPerformed(TablesFrame.java:124)

TablesFrame.java:124 entspricht folgender Zeile:

```
EntityManager em = emf.createEntityManager();
```
Kommentier ich die Zeilen des EntityManager aus funktioniert mein Programm wie geplant. Das begin und commit wäre für mich aber sehr wichtig. Was mach ich falsch?

Viele Grüße
CroweHammer


----------



## Tharsonius (5. Feb 2010)

```
EntityManagerFactory emf = null;
EntityManager em = emf.createEntityManager();
```

emf ist null, weist Du dem ja selber zu. Die drauf folgende Zeile kann natürlich nur eine NPE werfen.

Du musst natürlich für emf erst ein Objekt erstellen, von dem Du dann createEntityManager() aufrufen kannst.


----------



## CroweHammer (5. Feb 2010)

Wenn ich etwas dergleichen mache,

```
EntityManagerFactory emf = new EntityManagerFactory();
EntityManager em = emf.createEntityManager();
```
muss ich alle abstrakten Methoden von EntityManagerFactory implementieren, dass muss doch zu umgehen sein?


----------



## Tharsonius (5. Feb 2010)

Ich habs nicht ausporbiert aber kannst Du das vielleicht wie BorderFactory auch einfach nutzen, ohne ein Objekt davon zu erstellen?

Also beispielsweise: 
	
	
	
	





```
EntityManager em = EntityManagerFactory.createEntityManager();
```


----------



## CroweHammer (5. Feb 2010)

Nein, geht leider auch nicht, siehe:

```
EntityManager em = EntityManagerFactory.createEntityManager();
```
non static method createEntityManager cannot be referenced from a static context
----------------------------------------------------------------------------------
HELP HELP HELP HELP HELP HELP


----------



## CNail187 (5. Feb 2010)

Hallo!

Du benötigst IMHO schon eine Instanz der Factory.
Ich gehe davon aus, dass du eine Desktop-Anwendung schreibst. Der Persistence Provider müsste dann folgendes möglich machen:


```
EntityManagerFactory emf = Persistence.createEntityManagerFactory("NameDeinerPersistenceUnit");
```

Dann kannst du so weiter machen wie du begonnen hast, also EntityManager von der Factory holen, usw.

In einem Application-Server-Umfeld kannst du dir die EMF auch injizieren lassen:

```
@PersistenceUnit(name = "NameDeinerPersistenceUnit" )
private EntityManagerFactory emf ;
```

Gruß, CNail


----------



## CroweHammer (5. Feb 2010)

okay danke, klingt schonmal ganz gut, aber irgendwie versteh ich nicht ganz, was ich bei der Persistence Unit eintragen muss?


----------



## CNail187 (5. Feb 2010)

Wo genau hapert es jetzt?

Wenn du JPA verwendest, benötigst du ja eine persistence.xml.
Dort gibst du unter anderem deiner persistence unit einen Namen.

[XML]
<persistence ...>
 <persistence-unit name="NameDeinerPersistenceUnit">
 ...
 </persistence-unit>
</persistence>
[/XML]


----------



## CroweHammer (5. Feb 2010)

Mein Problem ist die Definition der PersistenceUnit. 
Ich hab keine Ahnung was das ist und dementsprechend weiß ich nicht was ich für den Namen der PersistenceUnit eingeben muss.


----------



## CNail187 (5. Feb 2010)

OK, also ich denke du solltest dann etwas mehr Code posten bzw. schreiben was du genau machen willst. Da du mit EntityManagern usw. hantierst, dachte ich dass du JPA mit Hibernate oder Toplink oder sonstwas als Provider verwendest. (?) In dem Fall wäre das Wissen um die Persistence Unit aber eine zentrale Voraussetzung.

Weitere Infos z.Bsp. hier:
https://ls10-wiki.cs.uni-dortmund.de/sopra/tutorials/jpa

Using the Java Persistence API in Desktop Applications

Oder verwendest du reines JDBC? Da kann man transaktionsmäßig ja auch ein wenig Einfluss nehmen, dann aber ohne die Entity-Geschichten:

Steuerung von Transaktionen mit JDBC


----------



## CroweHammer (5. Feb 2010)

Hey danke, ich arbeite rein mit JDBC. Ich denke, dass der untere Link genau das ist was ich brauche.
Ich hab jetzt allerdings Feierabend und werde das dann spät. am Montag Vormittag ausprobieren und bei Erfolg dir gleich mal meinen Dank im Forum zukommen lassen.
Schönes Wochenende wünsche ich!

Grüße CroweHammer


----------



## CNail187 (5. Feb 2010)

Na dann, viel Erfolg und ebenfalls ein schönes WE!

Gruß,
CNail


----------



## CroweHammer (8. Feb 2010)

sers, ich wollte es jetzt mal so lösen, dass er im Erfolgsfall abschließt, im Falle der Exception das Rollback ausführt.

```
public int updateDB(String query_insert_user) {
         try {           
            int n = stmt.executeUpdate(query_insert_user);
            System.out.println("DB-Info: "+ n + " Lines updated");
            // Wenn keine Fehler aufgetreten sind, Änderungen festschreiben.
            connection.commit();
            return n;
         } catch (SQLException e) {
            connection.rollback();
            return -1;
        }
}
```
Jetzt wird noch eine SQLException um connection.rollback() gefordert, aber in den catch-Block nochmal eine try-catch reinzubasteln macht doch irgendwie keinen Sinn oder?


----------



## CNail187 (8. Feb 2010)

Naja, das ist - unabhängig von der Datenbankerei - eben ein grundlegendes Problem wenn riskante Methoden in einem catch-Block ausgeführt werden.

Eine ganz interessante Diskussion mit verschiedenen Lösungsansätzen findest du zum Beispiel hier:
Swallowing exception thrown in catch/finally block - Stack Overflow

Ein Patentrezept scheints dafür aber leider nicht zu geben...


----------



## CroweHammer (8. Feb 2010)

Sieht ganz so aus, als würde ich um die doppelte try-catch nicht drumherum kommen, falls jemand doch eine schickere Lösung kennt immer her damit. 
Ansonsten hake ich das Thema jetzt ab und ein recht herzliches Dankeschön an CNail187.

Gruß CroweHammer


----------

