hibernate.cfg.xml在运行时修改

时间:2014-03-05 14:36:38

标签: java hibernate

我有一个问题,有些人已经解决了,但问题是我不明白我的实施中缺少什么。

我的部分hibernate代码如下:

<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
    <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/Database</property>
    <property name="hibernate.connection.username">username</property>
    <property name="hibernate.connection.password">password</property>

问题是我想通过更改hibernate.connection.url属性中的“database”字来选择我想在运行时使用的数据库。

在javaswing中,我正在实现这个功能:

public static void SetSessionFactory(String url) {
    try {

  AnnotationConfiguration conf = new AnnotationConfiguration().configure();
   // <!-- Database connection settings -->
  conf.setProperty("hibernate.connection.url", url);
  SessionFactory SESSION_FACTORY = conf.buildSessionFactory();

  //DEBUG1=With this output I intend to check if the parameter has changed
  System.out.println("Connection changed to " + conf.getProperty("hibernate.connection.url"));

} catch (Throwable ex) {
  // Log exception!
  throw new ExceptionInInitializerError(ex);
}

}

然后,我检查使用按钮所做的更改,从组合框中选择我想要的数据库:

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
       String url;
        int areaIndex = this.areaComboBox.getSelectedIndex();

      switch (areaIndex) {
        case 0:
            url="jdbc:postgresql://localhost:5432/Database";
            break;
        case 1:
            url="jdbc:postgresql://localhost:5432/Database1";
            break;
        case 2:
            url="jdbc:postgresql://localhost:5432/Database2";
            break;
        default:
            url="jdbc:postgresql://localhost:5432/Database";
            break;
    }
    SetSessionFactory(url);   

  AnnotationConfiguration config = new AnnotationConfiguration().configure();
  //DEBUG2= With this output I want to confirm the changes of the property outside the setSessionFactory function
   System.out.println("DATABASE= " + config.getProperty("hibernate.connection.url"));
}  

现在,debug1的输出正在改变,所以我在这个打印中获得了我想要的数据库的名称,但是debug2的输出没有改变。不用说,我的其余代码可以访问未更改的数据库,而不是我想从运行时访问的数据库。

如何在运行时修改此值?

非常感谢!

2 个答案:

答案 0 :(得分:5)

我找到了解决问题的方法。问题是,当我想在其余代码中使用新配​​置时,我无法为每个事务打开一个新会话(按照hibernate的建议),但那个会话是始终是hibernate.cfg.xml文件开头的那个。另外,我在一个按钮中定义了我的配置功能。

现在我改变了我的函数的位置并将它放在HibernateUtil.java中,只添加了我需要的配置以及稍后可能有用的配置

public static void SetSessionFactory(String url, String user, String pass) {
    try {

      AnnotationConfiguration conf = new AnnotationConfiguration().configure();
      // <!-- Database connection settings -->
      conf.setProperty("hibernate.connection.url", url);
      conf.setProperty("hibernate.connection.username", user);
      conf.setProperty("hibernate.connection.password", pass);
      sessionFactory = conf.buildSessionFactory();

    } catch (Throwable ex) {
      // Log exception!
      throw new ExceptionInInitializerError(ex);
    }
  }

然后,任何时候我想访问那个新连接,在每个事务开始时我调用会话指向同一个类HibernateUtil.java

public Session session = HibernateUtil.getSessionFactory().openSession();

如果不将第一个函数放在此类中,则打开的会话始终是配置文件中默认的会话。

答案 1 :(得分:0)

尝试此操作(将表A中登录字段的数据库main的ID 1复制到表C的电子邮件字段,数据库foregin的ID为1):

// config
SessionFactory mainSF = new Configuration()
  .addResource("A.hbm.xml")
  .addResource("B.hbm.xml")
  .setProperty("dialect", "org.hibernate.dialect.PostgreSQLDialect")
  .setProperty("connection.url", "jdbc:postgresql://your.first.db/main")
  .setProperty("connection.username","username")
  .setProperty("connection.password","password").buildSessionFactory();
SessionFactory foreginSF = new Configuration()
  .addResource("C.hbm.xml")
  .addResource("D.hbm.xml")
  .setProperty("dialect", "org.hibernate.dialect.PostgreSQLDialect")
  .setProperty("connection.url", "jdbc:postgresql://your.second.db/foregin")
  .setProperty("connection.username","username")
  .setProperty("connection.password","password").buildSessionFactory();

// pre business
Session main = mainSF.openSession();
Session foregin = foreginSF.openSession();
// now your buissness, ie:
A a = (A) main.get(A.class, 1);
C c = (C) foregin.get(C.class, 1);
Transaction foreginTransaction = foregin.beginTransaction();
c.setEmail(a.getLogin());
foregin.saveOrUpdate(c);
foreginTransaction.commit();

// post business
main.close();
foregin.close();