Skip to content

Instantly share code, notes, and snippets.

@schakko
Created January 30, 2014 07:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schakko/8703966 to your computer and use it in GitHub Desktop.
Save schakko/8703966 to your computer and use it in GitHub Desktop.
Dynamic properties inside persistence.xml
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>
* &lt;persistence-unit name=&quot;Example&quot;&gt;
* &lt;!-- Use our own provider so we can manage the properties --&gt;
* &lt;provider&gt;EnvironmentSpecificHibernatePersistence&lt;/provider&gt;
* &lt;jta-data-source&gt;jdbc/MyJTADataSource&lt;/jta-data-source&gt;
* &lt;properties&gt;
* &lt;property name=&quot;hibernate.transaction.factory_class&quot; value=&quot;org.hibernate.transaction.CMTTransactionFactory&quot;/&gt;
*
* &lt;!-- WebSphere specific setting; which is the default in production environment --&gt;
* &lt;property name=&quot;hibernate.transaction.manager_lookup_class&quot; value=&quot;org.hibernate.transaction.WebSphereExtendedJTATransactionLookup&quot;/&gt;
* &lt;property name=&quot;jta.UserTransaction&quot; value=&quot;java:comp/UserTransaction&quot;/&gt;
*
* &lt;!-- JBoss specific setting; the environment variable applicationserver.runtime has been set inside JBoss --&gt;
* &lt;!-- Remove the hibernate.transaction.manager_lookup_class setting --&gt;
* &lt;property name=&quot;?(applicationserver.runtime=jboss)hibernate.transaction.manager_lookup_class&quot; value=&quot;&quot; /&gt;
* &lt;!-- Overwrite the setting --&gt;
* &lt;property name=&quot;?(applicationserver.runtime=jboss)jta.UserTransaction&quot; value=&quot;java:comp/JBossUserTransaction&quot; /&gt;
* &lt;/properties&gt;
* &lt;/persistence&gt;
* </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