如何在不是来自JNDI的JPA EntityMangerFactory上设置DataSource

时间:2014-03-03 02:00:46

标签: java hibernate jpa

我对JPA很新,使用过JDO(DataNucleus)和Hibernate。

我了解如何为JPA配置设置persistence.xml,但我需要进行一次调整。我想要向DataSource提供实际的DataSource对象,而不是在XML中指定EntityManagerFactory。我需要这样做,因为我创建和管理自己的DataSource对象并且不依赖于容器这样做,因此我不能(并且不想)通过JNDI查找DataSource persistence.xml中的名称。

那么,如何向DataSource提供EntityManagerFactory对象,而不是在persistence.xml中指定它?我无法想象这很难做到,但我似乎找不到它,而且我到处都看了。

如果它有帮助,我正在使用Hibernate 4作为JPA提供者(实际上,我正在从3.6转换到4,Ejb3Configuration类已经消失了)。希望我能以非Hibernate特定的方式完成它,但如果我必须使用特定于Hibernate的API,这并不是一件大事。

谢谢!!!

-Ryan

2 个答案:

答案 0 :(得分:1)

我无法想办法自己这样做,所以我用Spring来做。这不一定是坏事,除了它要求我导入我以前不打算使用的六个左右的罐子。无论如何,我最终还是将它们用于其他事情,但是,我认为JPA真的失败了,人们甚至无法使用API​​来设置DataSource,而必须依赖于容器提供的DataSource。

我使用Spring的LocalContainerEntityManagerFactoryBean来完成工作。它从persistence.xml读取配置数据,然后通过Spring API设置DataSource。 Spring使用DataSource覆盖persistence.xml中定义的内容。

这是代码的样子。请注意对afterPropertiesSet方法的调用。这是必需的,因为我的应用程序不使用Spring进行依赖注入或AOP,而是将Guice用于这些任务。如果您不调用afterPropertiesSet方法,则对getNativeEntityManagerFactory的调用将返回null。

  LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
  factoryBean.setDataSource(dataSource);
  factoryBean.setPersistenceUnitName("persistenceUnitName");
  factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
  factoryBean.afterPropertiesSet();

  EntityManagerFactory factory = factoryBean.getNativeEntityManagerFactory();

答案 1 :(得分:0)

如果你没有使用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);

属性javax.persistence.nonJtaDataSource被记录为JNDI URL但使用Hibernate 5.1.4.Final工作正常。