Festlegen von JPA-Persistenzeigenschaften dynamisch

8

Nehmen wir an, ich habe die folgende persistence.xml mit der Verbindungs-URL, user & amp; Passwort ist fest codiert.

Das Folgende ist für Hibernate 3.2. Für Hibernate 3.5 ++ müssen wir "hibernate.connection" in "javax.persistence" ändern. Aber lassen Sie mich diese Frage unabhängig von den Literalen "hibernate.connection" oder "javax.persistence" stellen.

%Vor%

Allerdings müssen wir die URL, Benutzer & amp; Passwort dynamisch. Es gibt einen vorgeschlagenen Authentifizierungsserver, der die URL, den Benutzer & amp; Passwort. Damit müssen wir nicht die Myriaden von Webapps konfigurieren, die irgendeine Form von JDBC, Hibernate oder JPA verwenden. Neben dem Sicherheitsproblem, Passwörter in sichtbaren Textdateien nicht speichern / verwalten zu wollen.

Wie kann ich diese JPA-Eigenschaften für die JPA dynamisch festlegen? Ich suche zwei Arten von Antworten:

  1. Für eine JPA-unabhängige Lösung (Toplink, Eclipselink, Hibernate usw.) - Gibt es eine JPA-Funktionalität, mit der ich diese drei Eigenschaften dynamisch festlegen könnte?

  2. Wenn ich mich völlig auf Hibernate verlassen kann, abgesehen von der möglichen JPA Avenue, gibt es einen Weg dies zu erreichen, ohne den Spring-Rahmen mit einzubeziehen (was wie eine riesige Monstrosität mit Tentakeln überall aussieht)? / p>

Ich würde mich freuen, wenn Sie auch zwei Cents / Quids / Rupies auf JNDI einwerfen möchten und wie ich damit die Funktionalität der persistence.xml-Eigenschaften ersetzen könnte. Dies ist jedoch nicht die Priorität der Frage.

    
Blessed Geek 27.07.2012, 20:35
quelle

2 Antworten

7

Es hängt davon ab, wie Sie Ihre EntityManagerFactory bootstrappen. Mit den beiden spezifischen Methoden können Sie eine java.util.Map mit Werten übergeben. Diese Werte haben Vorrang vor Werten, die in der Persistenzeinheit definiert sind.

Beim "SE-Ansatz" gibt es kein Problem, da der Bootstrap-Prozess normalerweise von Ihrer App gesteuert wird: javax.persistence.Persistence#createEntityManagerFactory(String puName, Map config . Nun könnten Sie hier Probleme haben, wenn etwas anderes (ähem, Spring) den EMF für Sie "verwaltet" ...

Im "EE-Ansatz" ist mir kein guter globaler Ansatz bekannt. Diese Map of values ​​existiert immer noch im Bootstrapping, aber das Problem ist, dass der EE-Container derjenige ist, der diese Methode aufruft.

Ein Hibernate-spezifischer Ansatz, der in beiden Fällen funktionieren würde, wäre die Verwendung der Konfigurationsvariablenersetzung. Also würden Sie in Ihrer Persistenz-Einheit den Benutzernamen oder das Passwort mit ${some.key} definieren und Hibernate würde diese für Sie ersetzen. Ob dies funktioniert, hängt davon ab, wie Sie diese Werte letztendlich festlegen möchten. Hibernate benötigt weiterhin Zugriff auf einen Konfigurationswert namens some.key , damit dies funktioniert ...

Noch ein weiterer "globaler Ansatz" ... Der "EE-Ansatz" zum Bootstrap des EMF besteht darin, dass der Container den javax.persistence.spi.PersistenceProvider instanziiert und seinen javax.persistence.spi.PersistenceProvider # createContainerEntityManagerFactory aufruft. createContainerEntityManagerFactory hat hier eine interessante Signatur. Im Wesentlichen wird eine javax.persistence.spi.PersistenceUnitInfo übergeben, die eine Objektdarstellung der geparsten Persistenzeinheit plus einige andere Dinge darstellt. Eine Option wäre, diesen Ansatz zum Bootstrap zu verwenden und eine Instanz von javax.persistence.spi.PersistenceUnitInfo, die Sie selbst erstellen, zu übergeben. javax.persistence.spi.PersistenceProvider ist eine Schnittstelle. Um es zu instanziieren, müssen Sie den Provider kennen, den Sie verwenden möchten, und den FQN zu ihrem Impl. Aber das ist normalerweise kein Problem, da diese ziemlich bekannt sind.

Sie fragen speziell nach dem Erstellen / Poolen von JDBC-Verbindungen. Sie haben dort speziell zusätzliche Optionen. Sie könnten Ihren "Credential Service" DataSources erstellen lassen und Ihr JPA-Provider verwendet diese DataSource einfach. Alle JPA-Provider unterstützen das Auffinden von DataSources über JNDI-Lookup. In "EE Bootstrapping" können Providern auch eine DataSource übergeben werden, die über PersistenceUnitInfo # getJtaDataSource und / oder PersistenceUnitInfo # getNonJtaDataSource verwendet werden soll. Hibernate akzeptiert alternativ eine DataSource-Instanz anstelle der typischen Einstellung für den DataSource-JNDI-Namen. Wenn Sie DataSource (aus irgendeinem Grund) nicht verwenden möchten, besteht eine Hibernate-spezifische Alternative darin, Hibernate's ConnectionProvider-Vertrag selbst zu implementieren. Dies ist der Vertrag (Schnittstelle), den Hibernate benötigt, um JDBC-Verbindungen zu erhalten und freizugeben. Wenn Sie ConnectionProvider implementieren, können Sie die zugrunde liegenden Verbindungen beliebig konfigurieren.

Viele Optionen:)

    
Steve Ebersole 27.07.2012, 23:11
quelle
3

Für Ihre zweite Frage kann ich eine Hibernate-only-Lösung anbieten.

%Vor%     
chris.tian 27.07.2012 21:09
quelle

Tags und Links