[英]How to set a DataSource on a JPA EntityMangerFactory that is not from JNDI
I'm pretty new to JPA, having used JDO (DataNucleus) and Hibernate. 我对JPA相当陌生,曾经使用过JDO(DataNucleus)和Hibernate。
I get how to set up persistence.xml
for the JPA configuration, but I need to make one tweak. 我了解了如何为JPA配置设置
persistence.xml
,但我需要进行一些调整。 Instead of specifying the DataSource
in the XML, I want to provide the actual DataSource
object to the EntityManagerFactory
. 我想在
EntityManagerFactory
提供实际的DataSource
对象,而不是在XML中指定DataSource
。 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
. 之所以需要这样做,是因为我创建和管理自己的
DataSource
对象,并且不依赖于容器来执行此操作,因此,我不能(也不希望)通过persistence.xml
的JNDI名称查找DataSource
。
So, how to I provide a DataSource
object to the EntityManagerFactory
rather than specifying it in persistence.xml
? 因此,如何将
DataSource
对象提供给EntityManagerFactory
而不是在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). 如果有帮助,我将使用Hibernate 4作为JPA提供程序(实际上,我正在从3.6过渡到
Ejb3Configuration
类消失的4)。 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. 希望我可以以非Hibernate特定的方式进行操作,但是如果我必须使用Hibernate特定的API的话,这并不是什么大问题。
Thank you!!! 谢谢!!!
-Ryan -Ryan
I couldn't figure out any way to do it myself so I used Spring to do it. 我自己想不出任何办法,所以我用Spring来做。 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.
我最终还是将它们用于其他用途,但是,我仍然认为JPA的真正失败是,它甚至不能使用API来设置数据源,而必须依赖于容器提供的数据源。
I used Spring's LocalContainerEntityManagerFactoryBean
to do the work. 我用Spring的
LocalContainerEntityManagerFactoryBean
来完成这项工作。 It reads the configuration data from persistence.xml
and I then set the DataSource
via the Spring API. 它从
persistence.xml
读取配置数据,然后我通过Spring API设置DataSource
。 Spring uses the DataSource
to override what was defined in persistence.xml
. Spring使用
DataSource
覆盖persistence.xml
中定义的内容。
Here's what the code looks like. 代码如下所示。 Note the call to the
afterPropertiesSet
method. 请注意对
afterPropertiesSet
方法的调用。 This is required because my application does not use Spring for dependency injection or AOP, but instead uses Guice for those tasks. 这是必需的,因为我的应用程序不将Spring用于依赖项注入或AOP,而是将Guice用于这些任务。 If you don't call the
afterPropertiesSet
method then the call to getNativeEntityManagerFactory
returns null. 如果不调用
afterPropertiesSet
方法,则对getNativeEntityManagerFactory
的调用将返回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: 如果您不使用Spring,则可以直接执行以下操作:
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. 属性
javax.persistence.nonJtaDataSource
被记录为JNDI URL,但使用Hibernate 5.1.4.Final可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.