Archivo mensual: octubre 2013

Spring and JPA: configuring Spring programmatically for Hibernate, EclipseLink, OpenJpa and DataNucleus

Here is my take at configuring Spring programmatically to support the more popular JPA providers out there: Hibernate, EclipseLink, OpenJpa and DataNucleus.

I am assuming you already know how to programmatically configure a data source, as well as how to use the @Configuration annotation. I’m just providing the @Bean definition for the entity manager factory.

Shared code

The following bean definition code provides common code shared by all JPA providers, and then calls configureProvider: we will isolate all provider specific code in that method.

@Bean
public LocalContainerEntityManagerFactoryBean 
  entityManagerFactory() throws PropertyVetoException 
{
  LocalContainerEntityManagerFactoryBean result =
    new LocalContainerEntityManagerFactoryBean();

  // loadTimeWeaver will be available if 
  //   @EnableLoadTimeWeaving is specified in this 
  //   config class (annotated with @Configuration)
  result.setLoadTimeWeaver(loadTimeWeaver);

  // coreDs should be a DataSource bean, 
  //   configured elsewhere.
  result.setDataSource(coreDs);

  Properties jpaProperties = new Properties();
  // ** Configuration common to all JPA 2.0 managers
  // coreDsDriverName is the database driver name!
  //    used to configure the datasource AND the 
  //    JPA provider
  jpaProperties.put( "javax.persistence.jdbc.driver", 
                     coreDsDriverName);

  // ** Provider specific config isolated here
  configureProvider(jpaProperties, result);

  result.setJpaProperties(jpaProperties);
  result.afterPropertiesSet();
  return result;
}

With this configuration you will have to provide your persistence.xml file. Just do not put a <provider> entry there: it will not be needed, we are specifying the provider programmatically.

However, if you want to remove the persistence.xml file, you can do that by specifying the packages to scan for entities programmatically, calling result.setPackagesToScan.

EclipseLink configuration

This is my very basic EclipseLink configuration. You should add EclipseLink specific configuration properties to jpaProperties, and provide configuration data to the entity manager factory bean (emf) so that it can instantiate the right provider.

private void configureProvider(Properties jpaProperties, 
     LocalEntityManagerFactoryBean emf) {
  // We want EclipseLink to recreate the database schema
  jpaProperties.put("eclipselink.ddl-generation", 
                    "drop-and-create-tables");
  emf.setJpaVendorAdapter(
    new EclipseLinkJpaVendorAdapter());
}

Hibernate configuration

This is my very basic Hibernate configuration:

private void configureProvider(Properties jpaProperties, 
     LocalEntityManagerFactoryBean emf) {
  // We want Hibernate to recreate the database schema
  jpaProperties.put(
        org.hibernate.cfg.Environment.HBM2DDL_AUTO, 
        "create-drop");
  // And we want Hibernate!
  emf.setJpaVendorAdapter(
     new HibernateJpaVendorAdapter());
}

OpenJpa configuration

OpenJpa basic configuration follows:

private void configureProvider(Properties jpaProperties, 
     LocalEntityManagerFactoryBean emf) {
  // We want EclipseLink to recreate the database schema
  jpaProperties.put("openjpa.jdbc.SynchronizeMappings", 
                    "buildSchema");
  jpaProperties.put("openjpa.InitializeEagerly", 
                    "true");

  emf.setJpaVendorAdapter(
     new OpenJpaVendorAdapter());
}

DataNucleus configuration

If you are using DataNucleus as your persistence provider, you are a bit out of luck, as Spring does not implement a vendor adapter for DataNucleus. We need to use a different approach, as follows.

private void configureProvider(Properties jpaProperties, 
     LocalEntityManagerFactoryBean emf) {
  // We want DataNucleus to recreate the database schema
  jpaProperties.put("datanucleus.autoCreateSchema", 
                    "true");
  emf.setPersistenceProviderClass(
     org.datanucleus.api.jpa.PersistenceProviderImpl.class);
}

Thats’ it!

DirectJNgine & the JEE-DJN connector 2.3 beta 1 are publicly available

The DirectJNgine 2.3 beta 1 as well as the JEE-DJN connector are now publicly available!

The main feature in DJN 2.3 will be support for pluggable adapters that will allow users to support integration with Spring, CDI/JEE, Guice, etc.

That means that it will be possible to define action classes as beans and inject Spring beans, CDI/JEE beans, etc. in them, making it very easy to work with Spring, CDI, etc.

Beta 1 is providing support just for the JEE-DJN connector, and can be downloaded from the DirectJNgine site.

Spring-DJN: integrating Spring into DirectJNgine

I have created an Spring connector for DirectJNgine, spring-djn which is currently in alpha!

This connector will integrate Spring into DirectJNgine, making it possible to use Spring beans as Ext Direct actions. This means that you will be able to get the benefits of Spring built-in lifecycle support. Besides, you will be able to inject Spring beans into your own action classes, greatly simplifying Spring usage with ExtJs.

The beta version of spring-djn should be made public in two to three weeks.