質問

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

役に立ちましたか?

解決

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();

他のヒント

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top