Salem's Euphoria

Sharing Experience

Dynamic Hibernate Context Switching

1 Comment

 Dynamic context switching

Commonly, in a web application, only one database is needed.  On a J2EE application, the context defined in the webApplicationContext.xml is a static configuration file with one database(as far as I know). Furthermore, we need Associating entities through mapping files(hbm.xml) or with directly annotated classes.  But what if we need to create databases dynamically and switch between them?
This approach, dynamic DB creation, may have its drawbacks, but it may be a fatality in some cases.

Here is a demonstration of dynamic database creation and dynamic context switching.

First , we need the database creation script(create_script.sql).

CREATE TABLE 'Person' (
'id' int(11) NOT NULL auto_increment,
'name' varchar(20) default NULL,
'country' varchar(100) default NULL,
'adress' VARCHAR(20) default NULL,
PRIMARY KEY  ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

And then create the database manually given its name:

java.sql.Connection connection = null;
try{
     connection=DriverManager.getConnection("[jdbc:mysql://dbserver:port]",user, pwd);
     java.sql.Statement stm=connection.createStatement();
     stm.executeUpdate(" CREATE DATABASE "+myDbName);
     String[] cmd = new String[]{"mysql", myDbName,
     "--user= "+user,
     "--password="+root ,
     "-e",
     "\"source  [fullPathto]\\create_script.sql\""
     };
     Runtime rt = Runtime.getRuntime>();
     Process proc = rt.exec(cmd);
     proc.waitFor();
}catch(Exception e){
     logger.fatal(e.getMessage());
}

I used MySql in this sample, thus, it should be in path environment variable. User and pwd variables are your server specific username and password. The fullPathTo is the full path directory to your create_table.script.

The database now created and populated, we have to make it accessible through a hibernate Context. I prefer using annotation for mapping but it can also been done with xml mapping files.  The context template looks like (hbtConf.xml):


<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <property name="connection.url">
      XXX
    </property>
    <property name="connection.username">root</property>
    <property name="connection.password">root</property>
    <property name="connection.driver_class">
      com.mysql.jdbc.Driver
    </property>
    <property name="dialect">
      org.hibernate.dialect.MySQLInnoDBDialect
    </property>
    <property name="current_session_context_class">thread</property>
    <property name="hibernate.show_sql">true</property>
    <property name="configurationClass">
      org.hibernate.cfg.AnnotationConfiguration
    </property>
    <mapping class="com.slm.entity.Person" />
</session-factory>
</hibernate-configuration>

Note that the “connection.url” was not set intentionally, it will be set later on the code while loading the context.

And here our person class :

@Entity
@Table(name = "person")
public class Organisme implements Serializable {
private static final long serialVersionUID = 10L;
@Id
@Basic(optional = false)
@Column(name = "id")
private String id;
@Column(name = "name")
private String name;

@Column(name = "country")
private String country;

@Column(name = "adress")
private String adress;

//constructor, getters and setters, equal and hash …

}

Now, we’ll load the Annotated Configuration file, and set the connection.url property to fit our newly created database.

SessionFactory sf = null;
Session ss = null;
try{
    Configuration conf =new AnnotationConfiguration().
    configure("hbtConf.xml");
    conf.setProperty("hibernate.connection.url", serverRoot+myDbName);
    sf = conf.buildSessionFactory();
    ss = sf.getCurrentSession();
}catch (Exception e) {
    logger.error("session creation problem \nMSG:" +e.getMessage()+ "\nCause: " + e.getStackTrace().toString());
}

Setting the hibernate.connection.url manually to the new destination would select the intended database. You may have other properties to set manually if you’re using Lucene indexes for example:

   conf.setProperty("hibernate.search.default.indexBase", indexRootFolder + myContextualIndexDirectoryName);

That’s all for dynamic context switching.

Advertisements

Author: Salem Ben Afia

Big Data & Java developer Search Engine Architect, Lucene Expert

One thought on “Dynamic Hibernate Context Switching

  1. Well I really enjoyed reading it. This article procured by you is very effective for proper planning.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s