# JPA und "persistence-unit"



## fsicher (24. Feb 2011)

Hallo 

In einem Projekt, in dem die JPA mit Hibernate eingesetzt wird, möchte ich den Namen der Db aus einer _Property_-Datei einlesen (auch weitere Parameter wir _url_, _username_, _password _usw.). Die Properties werden eingelesen und in eine Mappe geschrieben, die beim erzeugen der _EntityManagerFactory _als Parameter übergeben wird. Das will aber irgendwie nicht!

Da ich die meisten Properties einlese, halte ich die _persistence.xml_ sehr kurz: 

[XML]
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
	xmlns="http://java.sun.com/xml/ns/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_1_0.xsd">
	<persistence-unit name="my_db" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>

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

Frage 1: 
Gehe ich richtig in der Annahme, dass man auf die _persistence.xml_ nicht verzichten kann? Und auch dann nicht, wenn sie so kurz gehalten wird? Mir ist es halt nicht gelungen ...

Frage 2:
Mein Ansatz funktioniert nur dann, wenn der Name der Datenbank mit dem Namen der "persistence-unit" übereinstimmt. Heisst, in meinem Beispiel hier, muss meine Db unbedingt *my_db* heissen. Versuche ich in der property-Datei die Db *test_db* zu taufen, bekomme ich folgende Fehlermeldung: 

[XML]javax.persistence.PersistenceException: No Persistence provider for EntityManager named test_db[/XML]

Also, geht das überhaupt? Könnte man den Db-Namen dynamisch aus einer property-Datei einlesen?

Und, noch ein Hinweis: es handelt sich um JPA und Hibernate mit JSE (kein AS).

Danke.


----------



## mvitz (24. Feb 2011)

Hallo,

du solltest den Teil, in dem du die Propertywerte ausliest und die EMF programmatisch erzeugst auch posten, den genau dort wird der Fehler zu finden sein.

Soweit ich weiß, muss es eine persistence.xml geben (kann mich da aber auch irren). Der Name der DB muss auf jeden Fall nicht mit dem Namen der persistence-unit übereinstimmen, da wirst du vermutlich irgendwo einen Fehler machen.


----------



## fsicher (24. Feb 2011)

Vielen Dank. 

Hier die Klasse und die property-Datei: 


```
package ch.hslu.wi.swc.boerse.db.util;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {
	private static final EntityManagerFactory entityManagerFactory;

	static {
		try {
			/* Properties laden */
			Properties props = new Properties();
			 InputStream is =
			 JPAUtil.class.getResourceAsStream("jpa.properties");
			props.load(is);

			Map<String, Object> configs = new HashMap<String, Object>();

			configs.put("javax.persistence.provider",
					props.getProperty("javax.persistence.provider"));
			configs.put("javax.persistence.transactionType",
					props.getProperty("javax.persistence.transactionType"));
			configs.put("hibernate.connection.driver_class",
					props.getProperty("hibernate.connection.driver_class"));

			/* url */
			String url = props.getProperty("hibernate.connection.url");

			configs.put("hibernate.connection.url", url);
			configs.put("hibernate.connection.username",
					props.getProperty("hibernate.connection.username"));
			configs.put("hibernate.connection.password",
					props.getProperty("hibernate.connection.password"));
			configs.put("hibernate.cache.provider_class",
					props.getProperty("hibernate.cache.provider_class"));
			configs.put("hibernate.show_sql",
					new Boolean(props.getProperty("hibernate.show_sql")));
			configs.put("hibernate.hbm2ddl.auto",
					props.getProperty("hibernate.hbm2ddl.auto"));

			int n = url.lastIndexOf("/");
			String dbName = url.substring(n + 1);

			/* EntityManagerFactory erzeugen */
			entityManagerFactory = Persistence.createEntityManagerFactory(
					dbName, configs);

		} catch (Throwable e) {
			System.out
					.println("\nEntityManagerFactory konnte nicht angelegt werden!\n\n"
							+ e);

			throw new ExceptionInInitializerError(e);
		}
	}

	public static EntityManagerFactory getEntityManagerFactory() {
		return entityManagerFactory;
	}
}
```

Die property-Datei:

[XML]
# Konfigurationsdatei
javax.persistence.transactionType=RESOURCE_LOCAL
javax.persistence.provider=org.hibernate.ejb.HibernatePersistence
hibernate.connection.driver_class=org.postgresql.Driver
hibernate.connection.url=jdbcostgresql://localhost:5432/my_db
hibernate.connection.username=postgres
hibernate.connection.password=postgres
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create
[/XML]

So funktioniert es. Wenn ich aber in der property-Datei die Db 'test_db' taufe, geht es nicht mehr. Es sei denn, das Attribute *name* der *persistence-unit * kann auch als Property gesetzt werden ... Aber wie?


----------



## mvitz (24. Feb 2011)

Kann der Name in der persistence.xml nicht konstant sein? Denn genau dort wo du dbName nutzt, muss nun mal der Name der persistence-unit übergeben werden.


----------



## fsicher (24. Feb 2011)

> Kann der Name in der persistence.xml nicht konstant sein?



In der Tat: der Name kann konstant bleiben!

Der Name der _persistence-unit_ kann konstant bleiben und somit fest codiert werden, während der Db-Name beliebig geändert werden kann. Aus irgendeinem Grund war ich der Ansicht, dass der Name der _persistence-unit_ mit dem Namen der Db identisch sein muss ???:L 

Vielen Dank.


----------

