Reputation: 791
I'm pretty new to JPA, having used JDO (DataNucleus) and Hibernate.
I get how to set up persistence.xml
for the JPA configuration, but I need to make one tweak. Instead of specifying the DataSource
in the XML, I want to provide the actual DataSource
object to the EntityManagerFactory
. I need to do this because I create and manage my own DataSource
objects and do not rely on the container to do so, thus I cannot (and do not want to) look up the DataSource
via a JNDI name in persistence.xml
.
So, how to I provide a DataSource
object to the EntityManagerFactory
rather than specifying it in persistence.xml
? I can't imagine it's hard to do but I can't seem to find it, and I've looked all over the place.
If it helps at all, I'm using Hibernate 4 as the JPA provider (actually, I'm transitioning from 3.6 to 4, where the Ejb3Configuration
class is gone). Hopefully I can do it in a non-Hibernate specific way, but it's not a huge deal if I have to use Hibernate specific APIs.
Thank you!!!
-Ryan
Upvotes: 2
Views: 10967
Reputation: 838
If your are not using Spring you can do directly:
Map<String, Object> props = new HashMap<String, Object>();
props.put("javax.persistence.nonJtaDataSource", createDataSource());
props.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistenceUnitName", props);
The property javax.persistence.nonJtaDataSource
is documented as a JNDI URL but using Hibernate 5.1.4.Final works fine.
Upvotes: 3
Reputation: 791
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();
Upvotes: 2