I couldn't figure out any way to do it myself so I used Spring to do it. That's not necessarily bad, except that it required me to import a half dozen or so jars that I previously wasn't intending to use. I ended up using them for other things anyway, but still, I think it's a real failure on the part of JPA that one can't even use the API to set a DataSource but must instead rely on a container-provided DataSource.
I used Spring's LocalContainerEntityManagerFactoryBean
to do the work. It reads the configuration data from persistence.xml
and I then set the DataSource
via the Spring API. Spring uses the DataSource
to override what was defined in persistence.xml
.
Here's what the code looks like. Note the call to the afterPropertiesSet
method. This is required because my application does not use Spring for dependency injection or AOP, but instead uses Guice for those tasks. If you don't call the afterPropertiesSet
method then the call to getNativeEntityManagerFactory
returns null.
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setPersistenceUnitName("persistenceUnitName");
factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
factoryBean.afterPropertiesSet();
EntityManagerFactory factory = factoryBean.getNativeEntityManagerFactory();