Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Monday, January 2, 2012

Hibernate Entity Generation Using Ant

Why would someone like to generate the sources from ant if its very easily generated through the IDE. The answer is simple: In a development environment different developers will use different versions of eclipse which will result in slightly different entities being generated. To provide the consistency across the team its better to have a ant or maven to generate the sources rather than rely on ide tools configuration.

Its very simple to generate the sources from ant's build.xml.

lets go through step by step


Build.xml is the file that the Ant uses to build the project. It has different tasks which we can use to perform different actions like compile, making jars, making wars, deployment etc. We will be using build.xml to generate sources. Hibernate tools comes with a predefined task which is org.hibernate.tool.ant.HibernateToolTask which is present in hibernate tools jar. We will be using this task to generate the sources.

1 Write a hibernate configuration file (a xml file.) which provides with all the details which the hibernate will require to connect to database. Hibernate will require
Username: username of the database
Password: password of the database
Schema: The name of the schema of the database
Driver: The driver to the database. For oracle its oracle.jdbc.OracleDriver
Connection Url: The connection url with portnumber, protocol and hostname.
Dialect: The dialect. For oracle 10 with hibernate its org.hibernate.dialect.Oracle10gDialect

At the end it will look like below.
oracle.jdbc.OracleDriver
development

username
password
org.hibernate.dialect.Oracle10gDialect


2 Write a reveng file which is an xml file which says which table metadata to be taken and converted to source.
For example:



3 Create a strategy class for the generation of classes. This strategy class will define the template for the source file generated. We will define this file to customize our class generation. We use HibernateCustomStrategy for our strategy. By default Hibernate tools provides with its own implementation.
4 Create a build.xml with the target. The class name mentions which class to be evoked when running this task. We will be using the predefined class HibernateToolTask which is present in the hibernate-tools.jar. Class path ref is the reference to the class path. For example
Create a path element. This element says that all the jar files in the lib directory will be part of this path.








We will refer this path element in the classpathref like below.






in ant task to generate the xml mapping files and uncomment to generate the DAOs.
11 To run this build.xml you can choose to use command line or through an IDE.
11.1 To run from the command line go to the directory of the build file. Use ant to run the build.xml. Note: You should have ANT_HOME set in your environment variable.
11.2 To run from Eclipse. Change the view to ant view. And double click on the targetname.
12 Check in the for the generated source.

Monday, December 19, 2011

Encrypting the password in the configuration files of MYBATIS

In the configuration file of ORM tools like hibernate , mybatis, jpa we have a common concern that the password of the database is exposed to each and every developer or whoever has the access to the code. It’s a great security concern for the enterprise which has the sensitive data in the database. So there comes the need to have an encrypted password in the configuration file and read it programmatically and make the decrypted password available to the application only at the run time. So that no one can read the password.
We can achieve this through any encryption codec algorithm providers like apache, sun and many more. I am demonstrating here using apache codec which is opensource library to encrypt and decrypt the password. I am demonstrating it for mybatis but the same can be achieved through similar process in hibernate or JPA.
We have a database properties file which contains all the database related properties like username, password, driver and url. The configuration file reads from this property file. We will be storing the password (in encrypted form in this property file) and while reading we will decrypt the password and give it to the builder for creating a sqlSession. To write to the database properties file we will use the command line argument to provide it with the properties file.
Lets have a look at the properties file:
driver=com.ibm.db2.jcc.DB2Driver
url=jdbc:db2://localhost:50000/CDR
username=db2admin
password=VXR!tre6g

Lets have a look at the configuration.xml file.

















]]>



Lets have a look at the PasswordService.java file which will write to the database.properties file and will have functions like encrypt and decrypt the password.
public final class PasswordService {
private static PasswordService instance;

public PasswordService() {
}

public synchronized String encrypt(String plaintext) throws Exception {
if(plaintext != null)
return new String(Base64.encodeBase64(plaintext.getBytes()));
return null;
}

public synchronized String decrypt(String plaintext) throws Exception {
if(plaintext != null)
return new String(Base64.decodeBase64(plaintext.getBytes()));
return null;
}
public static synchronized PasswordService getInstance()
{
if (instance == null) {
instance = new PasswordService();
}
return instance;
}
public static void main(String args[]){
try {
String encryped = getInstance().encrypt(args[0]);
Properties prop = new Properties();
InputStream in = ConnectionFactory.class.getResourceAsStream("prop.properties");
prop.load(in);
Properties databaseprop = PropsUtils.load(prop.getProperty("databasepropertiesfile"));
Enumeration e = databaseprop.keys();
while(e.hasMoreElements()){
String str = (String)e.nextElement();
if(str.equals("password")){
databaseprop.setProperty("password", encryped);
}
}
URL url = ClassLoader.getSystemResource(prop.getProperty("databasepropertiesfile"));
FileOutputStream fos =new FileOutputStream(url.getFile());
databaseprop.store(fos, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}


Lets have a look at the ConnectionFactory.java file which will create the sqlSession.

public class ConnectionFactory {

private static SqlSessionFactory sqlMapper;
private static Reader reader;
static {
try {
Properties prop = new Properties();
InputStream in = ConnectionFactory.class.getResourceAsStream("prop.properties");
prop.load(in);
Properties databaseprop = PropsUtils.load(prop.getProperty("databasepropertiesfile"));
String encrypedPassword = databaseprop.getProperty("password");
String password = PasswordService.getInstance().decrypt(encrypedPassword);
databaseprop.setProperty("password", password);
String conf =prop.getProperty("configurationfile");
reader = Resources.getResourceAsReader(conf);
sqlMapper = new SqlSessionFactoryBuilder().build(reader,databaseprop);

} catch (Exception e) {
e.printStackTrace();
}
}

public static SqlSessionFactory getSession() {
return sqlMapper;
}
}

Lets have a look at the PropUtils.java file

public class PropsUtils {
private PropsUtils() { }
/**
* Load a properties file from the classpath
* @param propsName
* @return Properties
* @throws Exception
*/
public static Properties load(String propsName) throws Exception {
Properties props = new Properties();
URL url = ClassLoader.getSystemResource(propsName);
props.load(url.openStream());
return props;
}

/**
* Load a Properties File
* @param propsFile
* @return Properties
* @throws IOException
*/
public static Properties load(File propsFile) throws IOException {
Properties props = new Properties();
FileInputStream fis = new FileInputStream(propsFile);
props.load(fis);
fis.close();
return props;
}
}

Thursday, June 7, 2007

Comparing Hibernate and JDBC (time issues)

I used JFluid(Performance Analysis tool) for my web application
Contact management.
The product uses Hibernate to interact with the database.
As an example I will take Hibernate methods and some statistics
to compare it with simple JDBC.

On the console when I started the server the output was this.




It has all the methods that the tomcat needs to start up. The profiling is perfect. It has four columns. The first column tells about the method name. The second one tells about the % of total time. The third one tells about the time in absolute terms and fourth one tells about the invocation time in absolute terms.

Now coming on the actual implementation.





In this picture one thing that is worth noting that the hibernate internally does not take as much of the time as the apache Catalina loader and other apache functionalities. Even the so called expensive process of creation of sessionFactory (87 ms this takes into account the time taken to read the configuration file and the time taken to build the factory.) taking no time in comparison to the server methods. But it takes comparatively higher times in comparison to other methods like getNamedQuery ( double the time than this 54ms ) and other methods like getterMehods (34 ms) still lesser time.

Now coming on to Hibernate specific methods.

We will divide the work of hibernate in three different categories.

· Loading of Configuration . It will include reading from the XML file, loading the mapping and getting the methods to deliver the result.

· Interaction with the database. It will include the creation of connection with the sql and the time taken to query and creation of tables.

· Displaying the result.

Before we take a dip into the categories I would like to say that the first category took around 0.75 times the time taken by second category. This can change drastically if we increase the number of users. Though the schema update time won’t change. The third category is not even in contention.

Among the categories that are listed above the time taken by the different category is

Coming onto the first category.

In the first category when we take out the methods those took the maximum amount of time are listed in the next paragraph.

The init() method of org.hibernate.cfg.Configuration() which is used to upload the configuration given in the hibernate.cfg.xml takes 2.9 ms. The add method of the same class takes 13.7 ms. The building of factory takes 5.62 ms and creationMapping() took 1.32 second. Rest all the processes took less than 1 ms. Creation of session(0.012ms) out of sessionFactory did not take much time ( as per the expectation., session is lightweight object) . So putting the creation of sessionFactory in the Plugin is the step in the right direction.

Moving onto the second category.

The second category mainly consists of one time process of dialect upload , creation of Connection and multiple time processes of query translation, sqlgenerator from HQL and fetching of data from the tables.

One time process of connection creation takes in total of 23 ms. The amount of time is spent in dialect upload ( that is equivalent of loading the driver in JDBC) is 43ms. Which compares badly with the direct JDBC Driver loading. Even the creation of connection takes more time than the usual JDBC connection creation.

This statistics can put Hibernate lover to think once again for the application where the time is important parameter. The other big demerit of Hibernate is the translation of HQL to sql that also takes 12 ms which can be saved in case of JDBC. Fetching data once the sql has been generated would take the same amount of time.