动态设置JPA持久性属性

Ble*_*eek 11 java hibernate jpa jpa-2.0

假设我有以下persistence.xml,连接url,用户和密码都是硬编码的.

以下是Hibernate 3.2.对于Hibernate 3.5 ++,我们必须将"hibernate.connection"更改为"javax.persistence".但是,无论文字"hibernate.connection"或"javax.persistence"如何,我都要问这个问题.

<persistence-unit name="obamacare" transaction-type="RESOURCE_LOCAL">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>
  <exclude-unlisted-classes>false</exclude-unlisted-classes>
  <properties>
    <property name="hibernate.archive.autodetection" value="class, hbm"/>
    <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="hibernate.connection.url" value="blah blah blah"/>
    <property name="hibernate.connection.username" value="careuser"/>
    <property name="hibernate.connection.password" value="carepass"/>
    <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
    <property name="hibernate.show_sql" value="true"/>
  </properties>
  </persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)

但是,我们需要动态设置网址,用户和密码.有一个提议的身份验证服务器,它提供URL,用户和密码.因此,我们不需要单独配置使用某种形式的jdbc,hibernate或JPA的无数webapp.除了不想在可见文本文件上存储/管理密码的安全问题.

就JPA而言,如何动态设置这些JPA属性?我正在寻求两套答案:

  1. 对于独立于JPA供应商的解决方案(toplink,eclipselink,hibernate等) - 是否有任何JPA功能可以让我动态设置这三个属性?

  2. 如果我被允许完全依赖Hibernate,除了可能的JPA唯一途径之外,有没有办法实现这一点而不涉及Spring框架(这似乎是一个巨大的怪物,触手遍布各处)?

如果您还希望在JNDI上投入两美分/ quids/rupe以及如何使用它来替换persistence.xml属性的功能,我会很高兴.但是,这不是问题的优先事项.

Ste*_*ole 7

这取决于你如何引导你的EntityManagerFactory.2个规范定义的方法每个允许您传入值的java.util.Map.这些值应该优先于持久性单元中定义的值.

在"SE方法"中没有问题,因为引导过程通常由您的应用程序控制:javax.persistence.Persistence#createEntityManagerFactory(String puName, Map config.现在你可能有问题,如果别的东西(ahem,Spring)为你"管理"EMF ......

在"EE方法"中,我不了解一种良好的全球方法.这个值的Map仍然存在于bootstrapping中,但问题是EE容器是调用此方法的容器.

在任何一种情况下都可以使用一种特定于Hibernate的方法是使用配置变量替换.因此,在您的持久性单元中,您将使用${some.key}Hibernate 定义用户名或密码,而Hibernate将替换您的用户名或密码.这是否真的有效取决于你最终想要如何设置这些值; Hibernate仍然需要访问为此命名的配置值some.key才能工作......

又一个"全局方法"......引导EMF的"EE方法"是容器实例化javax.persistence.spi.PersistenceProvider并调用它的javax.persistence.spi.PersistenceProvider #createContainerEntityManagerFactory.createContainerEntityManagerFactory在这里有一个有趣的签名.本质上它传递的是javax.persistence.spi.PersistenceUnitInfo,它是解析的持久性单元的对象表示以及其他一些东西.一个选项是使用这种方法来引导并传入一个构建你自己的javax.persistence.spi.PersistenceUnitInfo实例.javax.persistence.spi.PersistenceProvider是一个接口.要实例化它,您需要知道要使用的提供程序和FQN到它们的impl.但这通常不是问题,因为这些都是众所周知的.

您特别询问JDBC连接创建/池化.你有其他选择.您可以让您的"凭证服务"创建DataSources,而您的JPA提供程序只需使用该DataSource.所有JPA提供程序都支持通过JNDI查找定位DataSource.在"EE bootstrapping"中,提供者也可以通过PersistenceUnitInfo#getJtaDataSource和/或PersistenceUnitInfo#getNonJtaDataSource传递DataSource.Hibernate交替接受DataSource实例来代替典型的DataSource JNDI名称设置.如果您不想使用DataSource(出于某些奇怪的原因),Hibernate特定的替代方法是自己实现Hibernate的ConnectionProvider契约,这是Hibernate在需要时用来获取和释放JDBC连接的契约(接口).实现ConnectionProvider,您可以以任何您想要的方式配置底层连接.

很多选择:)