tags:

views:

718

answers:

2

JBOSS 5.1 / EJB 3 / JPA / MySQL

For development we specify "hibernate.hbm2ddl.auto" as "update". This is done in several persistence.xml files embedded in several jars in an ear.

For production we'd like to override this to specify "validate".

Can this be done via configuration external to the ear?

(I know it's possible to do this in code in a non-managed environment)

A: 

For standalone hibernate its easy to do, when you create the persistence object you can pass it a hash-table of key-value pairs. In your case the key "hibernate.hbm2dll.auto" and value of "validate"...

private Map properties = Util.newMap();

public EntityManagerFactory getEntityManagerFactory() {
    if (emf == null || !emf.isOpen()) {
        emf = Persistence.createEntityManagerFactory(PU, properties);
    }
    return emf;
}

public EntityManager getEntityManager() {
    if (em == null || !em.isOpen()) {
        em = getEntityManagerFactory().createEntityManager();
    }
    return em;
}

I then would have my configuration class populate the Map with things from my custom configuration file.

I don't believe you can modify an already open EntityManager instance. And though you can pass the EntityManager a Map, I found that it ignored those properties and only paid attention when you did it from the Factory...

Petriborg
Yes - in a non-managed environment you can do this. But how do you do it in a managed environment (e.g. JBOSS) when the EntityManager is obtained like so: @PersistenceContext private EntityManager em;
Conor
@conor Ah ok that makes sense... is the EM connection already opened for you?
Petriborg
Yes - it's injected by JBoss.
Conor
@conor ah then I'm not sure how you could do that, maybe somehow through JBoss? I don't use JBoss myself - our hibernate database application is standalone.
Petriborg
A: 

For JBoss 5.1 the following file needs to be edited:

<jboss_dir>/server/default/deployers/ejb3.deployer/META-INF/jpa-deployers-jboss-beans.xml

<bean name="PersistenceUnitDeployer" class="org.jboss.jpa.deployers.PersistenceUnitDeployer">
      <property name="defaultPersistenceProperties">
         <map keyClass="java.lang.String" valueClass="java.lang.String">
            <entry>
               <key>hibernate.transaction.manager_lookup_class</key>
               <value>org.hibernate.transaction.JBossTransactionManagerLookup</value>
            </entry>                
            <entry>
               <key>hibernate.hbm2ddl.auto</key>
               <value>validate</value>
            </entry>
            <entry>
               <key>hibernate.cache.provider_class</key>
               <value>org.hibernate.cache.HashtableCacheProvider</value>
            </entry>                
            <entry>
               <key>hibernate.jndi.java.naming.factory.initial</key>
               <value>org.jnp.interfaces.NamingContextFactory</value>
            </entry>
            <entry>
               <key>hibernate.jndi.java.naming.factory.url.pkgs</key>
               <value>org.jboss.naming:org.jnp.interfaces</value>
            </entry>
            <entry>
               <key>hibernate.bytecode.use_reflection_optimizer</key>
               <value>false</value>
            </entry>
            <!-- I don't think this is honored, but EJB3Deployer uses it -->
            <entry>
               <key>hibernate.bytecode.provider</key>
               <value>javassist</value>
            </entry>
         </map>
      </property>
</bean>

These properties can be edited in the following file in JBoss 4.2:

<jboss_dir>/server/default/deploy/ejb3.deployer/META-INF/persistence.properties

mtpettyp
Great - thanks - I will try this.
Conor
Ok - that works. To clarify: persistence.xml in jars/wars/ear override this file. So you need to update persistence.xml files so that they do not contain the (e.g.) hibernate.hbm2ddl.auto property.
Conor
Yes, I find it good practice to never set those properties in the persistence.xml unless they are the same for development and production.
mtpettyp