Question

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!

Was it helpful?

Solution

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.

OTHER TIPS

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top