【问题标题】:Insert external data into persistence.xml将外部数据插入persistence.xml
【发布时间】:2012-08-17 21:09:37
【问题描述】:

我希望我的 persistence.xml 动态设置它的一些属性,具体来说:

<property name="hibernate.connection.password" value="password"/>
<property name="hibernate.connection.username" value="username"/>

我可以构建一个可以为我提供所需数据的类,但我不知道如何以如下方式设置该类:

<property name="hibernate.connection.password" value="${my.clazz.pass}"/>
<property name="hibernate.connection.username" value="${my.clazz.user}"/>

我尝试过这样设置课程

public class clazz{

  String pass;
  String user;

  public clazz(){
    //do stuff to set pass and user
  }

  //getter/setter
}

但这不起作用。我在这里或在 google 中都没有找到方法,但我已经多次看到 ${my.clazz.smth} 方式。

那么,我该如何设置呢? :)

提前致谢!

【问题讨论】:

  • 如果您正在运行 Web 应用程序,您应该考虑使用 JNDI 查找。

标签: java xml spring


【解决方案1】:

所以,不久前解决了这个问题,但我仍然没有回答:

Anthony Accioly 为我指明了正确的方向:

我将此添加到我的 applicationContext.xml 的 entityManagerFactory

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitPostProcessors">
        <bean class="my.package.SetupDatabase">
        </bean>
    </property>
    //the other stuff
</bean>

对应的类,本例我使用hibernate:

package my.package;

public class SetupDatabase implements PersistenceUnitPostProcessor {

    private String username;
    private String password;
    private String dbserver;

    public void SetupDatabase(){
        //do stuff to obtain needed information
    }

    public void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
        pui.getProperties().setProperty("hibernate.connection.username", username );
        pui.getProperties().setProperty("hibernate.connection.password", password);
        pui.getProperties().setProperty("hibernate.connection.url", dbserver ); 
    }

}

这种方式在启动整个过程时只需完成一次设置,但所需的数据可能是“外包”的。

再次感谢您为我指明正确的方向!

【讨论】:

  • 我需要做同样的事情,但没有弹簧。我的情况有什么建议吗?
  • LocalContainerEntityManagerFactoryBean 还包含属性jpaProperties,无需PersistenceUnitPostProcessor 即可实现相同的效果。
  • @DanielArdison 您的问题可能与this 相关。
【解决方案2】:

您引用的值占位符${my.clazz.smth} 通常是从属性文件中读取的,而不是直接从类中读取的。

这是使用 Spring 的 PropertyPlaceholderConfigurer 完成的。

这是一个结合了 Hibernate 和 Spring 的项目的 example

【讨论】:

    【解决方案3】:

    如果您确实需要将配置延迟到运行时(例如,从外部来源(如 Web 服务)获取数据库凭据),您可以使用 Hibernate API Programatic Configuration 来完成,特别是对于旧版本的 Hibernate 或 Ejb3Configuration ServiceRegistryBuilder (v 4.X)...

    但请注意,据我所知,无法动态更新PersintenceUnit 的用户名和密码。每次需要更改其属性时,您都必须从新的 Configuration 实例(一个非常昂贵的操作)构建另一个 EntityManagerFactory。 无论如何,除非您有充分的理由,不要从您的应用程序管理数据库凭据,而是将其委托给 JNDI-Bound DataSource

    Ejb3Configuration cfg = new Ejb3Configuration()
      // Add classes, other properties, etc
      .setProperty("hibernate.connection.password", "xxxx")
      .setProperty("hibernate.connection.username", "yyyy"); 
    
    EntityManagerFactory emf= cfg.buildEntityManagerFactory();
    

    【讨论】:

    • 没错,我从另一个服务获取凭据,但我只需要在启动服务器时设置一次,并且不会让它们在源上直接可见。如果我找到一个解决方案,我会试试你的建议并发布一个解决方案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2018-07-11
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    相关资源
    最近更新 更多