【问题标题】:hibernate.cfg.xml modification on runtime运行时修改 hibernate.cfg.xml
【发布时间】:2014-03-05 14:36:37
【问题描述】:

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

我的部分休眠代码如下:

<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 属性中的“数据库”一词来选择我想在运行时使用的数据库。

在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 的输出没有改变。不用说,我的其余代码可以访问未更改的数据库,而不是我想从运行时访问的数据库。

如何在运行时修改此值?

非常感谢!

【问题讨论】:

  • 会话中附加的实体会发生什么?
  • 你指的是SessionFactory吗 SESSION_FACTORY = conf.buildSessionFactory(); ?说真的,我不完全确定,但我认为这条线是为了更新会话。我尝试在函数中返回它,而不是使用 void 函数,但我没有太大区别。我是否使用了错误的会话?
  • 有人知道我的代码中缺少什么吗?我还是卡住了。
  • SessionFactory != 会话。你使用短期会话吗?
  • 事实上我认为我应该这样做,但我不确定我这样做是否正确。这部分代码应该在我的应用程序开始时运行,我应该选择我要使用的数据库。然后,在完成我想要的计算之后,我希望能够为另一个数据库选择另一个连接并在不重新启动应用程序的情况下进行我想要的计算。为此,我已阅读我必须关闭会话并开始一个新会话。问题是我似乎还没有做到这一点。

标签: java hibernate


【解决方案1】:

我找到了解决问题的方法。问题是,当我想在其余代码中使用新配​​置时,我无法使用,因为对于每个事务,我都打开了一个新会话(如 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();

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

【讨论】:

    【解决方案2】:

    试试这个(将数据库main的ID为1的表A的登录字段复制到数据库foregin的ID为1的表C的电子邮件字段):

    // 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();
    

    【讨论】:

      猜你喜欢
      • 2015-01-15
      • 2020-07-21
      • 2010-12-08
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多