Dynamic properties inside persistence.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashMap; | |
import java.util.Map; | |
import javax.persistence.EntityManagerFactory; | |
import javax.persistence.spi.PersistenceProvider; | |
import javax.persistence.spi.PersistenceUnitInfo; | |
import org.hibernate.ejb.Ejb3Configuration; | |
import org.hibernate.ejb.HibernatePersistence; | |
/** | |
* <strong>This class does theoretically work, but not in practice. Thanks to | |
* the Java EE 6 standards.</strong><br /> | |
* Use this {@link PersistenceProvider} if you have properties inside your | |
* properties.xml that must be set inside different application server | |
* environments. I wrote this class for supporting Hibernate inside JBoss and | |
* WebSphere. All checked properties are retrieved through | |
* {@link System#getProperty(String)}. | |
* | |
* See this example persistence.xml | |
* | |
* <pre> | |
* <persistence-unit name="Example"> | |
* <!-- Use our own provider so we can manage the properties --> | |
* <provider>EnvironmentSpecificHibernatePersistence</provider> | |
* <jta-data-source>jdbc/MyJTADataSource</jta-data-source> | |
* <properties> | |
* <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/> | |
* | |
* <!-- WebSphere specific setting; which is the default in production environment --> | |
* <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/> | |
* <property name="jta.UserTransaction" value="java:comp/UserTransaction"/> | |
* | |
* <!-- JBoss specific setting; the environment variable applicationserver.runtime has been set inside JBoss --> | |
* <!-- Remove the hibernate.transaction.manager_lookup_class setting --> | |
* <property name="?(applicationserver.runtime=jboss)hibernate.transaction.manager_lookup_class" value="" /> | |
* <!-- Overwrite the setting --> | |
* <property name="?(applicationserver.runtime=jboss)jta.UserTransaction" value="java:comp/JBossUserTransaction" /> | |
* </properties> | |
* </persistence> | |
* </pre> | |
* | |
* @author ckl | |
* | |
*/ | |
@Deprecated | |
public class EnvironmentSpecificHibernatePersistence extends HibernatePersistence { | |
/** | |
* Create an entity manager factory from the given persistence unit info, | |
* using the specified properties (they override any on the PUI). | |
* <p/> | |
* This is the form used by the container in a JEE environment. | |
* | |
* @param info | |
* The persistence unit information | |
* @param properties | |
* The explicit property values | |
* | |
* @return initialized EntityManagerFactory | |
*/ | |
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) { | |
Map environmentProperties = parsePropertyExpressions(properties); | |
Ejb3Configuration cfg = new Ejb3Configuration(); | |
Ejb3Configuration configured = cfg.configure(info, properties); | |
return configured != null ? configured.buildEntityManagerFactory() : null; | |
} | |
/** | |
* Iterates over every entry of the properties map and checks for an | |
* expression like "?($environment=value)key...". If this expression | |
* evaluates to true, any property with name "key" will be overwritten. | |
* | |
* @param originalPersistenceXmlProperties | |
* @return | |
*/ | |
@SuppressWarnings({ "rawtypes", "unchecked" }) | |
public Map parsePropertyExpressions(Map originalPersistenceXmlProperties) { | |
HashMap r = new HashMap(); | |
HashMap overwriteLater = new HashMap(); | |
for (Object persistenceXmlKey : originalPersistenceXmlProperties.keySet()) { | |
if (persistenceXmlKey instanceof String) { | |
String key = (String) persistenceXmlKey; | |
// get positions of marker characters | |
int posExpressionBegin = key.indexOf("?("); | |
int posExpressionEnd = key.indexOf(")"); | |
int posExpressionEqual = key.indexOf("="); | |
// does the string match the format | |
// ?($systemProperty=$value)$key | |
if ((posExpressionBegin >= 0) && (posExpressionEnd > 0) && (posExpressionEqual > posExpressionBegin) | |
&& (posExpressionEqual < posExpressionEnd)) { | |
String systemPropertyToAssert = key.substring(posExpressionBegin + 2, posExpressionEqual); | |
String systemPropertyIsValue = key.substring(posExpressionEqual + 1, posExpressionEnd); | |
String valueOfSystemProperty = System.getProperty(systemPropertyToAssert); | |
String evaluatedPersistenceXmlKey = key.substring(posExpressionEnd + 1); | |
// is the system property defined? | |
if ((valueOfSystemProperty != null) && valueOfSystemProperty.equals(systemPropertyIsValue) | |
&& (evaluatedPersistenceXmlKey != null) && (evaluatedPersistenceXmlKey.length() > 0)) { | |
// retrieve the value of this key from persistence.xml | |
Object value = originalPersistenceXmlProperties.get(persistenceXmlKey); | |
// no value passed => remove key from properties | |
if (value == null || ((value instanceof String) && ((String) value).length() == 0)) { | |
r.remove(evaluatedPersistenceXmlKey); | |
} | |
// add new property value to the pushed properties | |
else { | |
overwriteLater.put(evaluatedPersistenceXmlKey, | |
originalPersistenceXmlProperties.get(persistenceXmlKey)); | |
} | |
} | |
} | |
} | |
// add every key | |
r.put(persistenceXmlKey, originalPersistenceXmlProperties.get(persistenceXmlKey)); | |
} | |
// overwrite specific keys | |
r.putAll(overwriteLater); | |
return r; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment