Harald Albers
Harald Albers

Reputation: 1992

How to set hibernate.hbm2ddl.auto on deployment in Wildfly NOT using persistence.xml

I need on deployment schema generation for a webapp that uses JPA. The server is Wildfly 9 with Hibernate as JPA provider.

I can achieve this by adding

<property name="hibernate.hbm2ddl.auto" value="create" />

to persistence.xml.

Is there another way to set this property per webapp and on deployment in Wildfly 9? I also tried hibernate.properties, but this had no effect.

Upvotes: 2

Views: 2894

Answers (3)

Born78
Born78

Reputation: 95

For wildfly you can use the ${env} expression with a default value:

<property name="mywebapp.hibernate.hbm2ddl.auto" value="${env.DB_AUTO:validate}"/>

Upvotes: 0

Tobias Liefke
Tobias Liefke

Reputation: 9022

There is no webapp specific deployment property out of the box.

But you can set a webapp specific system property which you reference in your persistence.xml:

<persistence-unit >
  ...
  <properties>
    <property name="hibernate.hbm2ddl.auto" value="${mywebapp.hibernate.hbm2ddl.auto}" />
  </properties>
</persistence-unit>

A system property can be set in the standalone.conf(.bat) or in the standalone.xml:

<server xmlns="urn:jboss:domain:3.0"> 
  <extensions> ... </extensions>
  <system-properties>
    <property name="mywebapp.hibernate.hbm2ddl.auto" value="create"/>
    ...
  </system-properties>
  ...
</server>

Only drawback: you will have to set the system property in every environment - there is no default value.

Another option is to create an Integrator which sets the value in the settings. Unfortunately the config is read into the Settings object at the beginning and Settings.setAutoCreateSchema() and the other hibernate.hbm2ddl.auto specific properties are package protected, but you can set them with reflection:

public class AutoCreateSchemaIntegrator implements Integrator {

  @Override
  public void integrate(Configuration config, SessionFactoryImplementor factory, 
            SessionFactoryServiceRegistry registry) {
    Settings settings = factory.getSettings();

    try {
      Method setter = settings.getClass().getDeclaredMethod("setAutoCreateSchema", boolean.class);
      setter.setAccessible(true);
      setter.invoke(settings, myDeploymentSpecificProperty);
    } catch (ReflectiveOperationException | SecurityException e) {
      // handle exception
    }
  }
}

You need to write the full qualified class name of that integrator into META-INF/services/org.hibernate.integrator.spi.Integrator:

com.myproject.AutoCreateSchemaIntegrator

This is the best option if you want to determine the hbm2ddl setting dynamically.

Upvotes: 3

Ricardo Vila
Ricardo Vila

Reputation: 1632

If you use Spring and JPA you can define all your persistence info in spring config xml. So you can include hibernate.hbm2ddl.auto to it. An example os Spring config file using org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean as EntityManagerFactory:

  <!-- DataSource reachable by jndi,  -->
  <jee:jndi-lookup id="myDataSource" jndi-name="jdbc/XADatasource" expected-type="javax.sql.DataSource" />

  <!-- jpa Properties used later in Hibernate configuration  -->
  <util:properties id="jpaHibernateProperties">
    <prop key="hibernate.transaction.jta.platform">
      org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform
    </prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    <!-- validate | update | create | create-drop --> 
    <prop key="hibernate.hbm2ddl.auto">create</prop>
    <prop key="hibernate.show_sql">false</prop>
    <prop key="hibernate.format_sql">false</prop>
    <prop key="javax.persistence.transactionType">JTA</prop>
    <prop key="javax.persistence.validation.mode">AUTO</prop>
  </util:properties>

  <!-- Entity manager definition. No need of persistence.xml -->
  <bean id="myEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
      </bean>
    </property>
    <property name="packagesToScan">
      <list>
        <value>com.mycompany.myproject</value>
      </list>
    </property>
    <property name="persistenceUnitName" value="myPU" />
    <property name="jtaDataSource" ref="myDataSource" />
    <!-- Hibernate specific params defined previously -->
    <property name="jpaProperties" ref="jpaHibernateProperties" />
  </bean>

Upvotes: 1

Related Questions