문제

I have this question that some people have already solved, but the thing is I don't understand what is missing in my implementation.

Part of my hibernate code is as follows:

<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>

the thing is that I want to select the database that I want to use in the runtime, by changing the "database" word in the hibernate.connection.url property.

In javaswing, I'm implementing this function:

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);
}

}

Then, I check the changes made with a button, selecting the database that I want from a combobox:

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"));
}  

Now, the output of the debug1 is changing, so I get in this print the name of the database that I want, but the output of the debug2 is not changing. Needless to say that the rest of my code have access to the unchanged database, not the one that I want to access from the runtime.

How can I get to modify this value on the runtime?

Thanks a lot!

도움이 되었습니까?

해결책

I found a way to solve my issue. The thing is that when I wanted to use the new configuration in the rest of the code I couldn't, 'cause for each transaction I opened a new session (as recommended by hibernate), but the that session was always the one that was at the beginning of the hibernate.cfg.xml file. Also, I was defining my configuration function in one button.

Now I changed the position of my function and put it in HibernateUtil.java, adding just the configurations that I needed and some that could be useful later

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);
    }
  }

And then, any time that I want to access to that new connection, at the beginning of each transaction I call the session pointed to the same class HibernateUtil.java

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

Without putting the first function in this class, the session that was being opened was always the one that was by default in the configuration file.

다른 팁

Try this (copies the login-field from table A with id 1 of database main, to the email-field of table C with id 1 of database foregin):

// 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();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top