Tuesday, June 1, 2010

HibernateDaoSupport with HibernateTemplate - defaultAutoCommit set false...

I am working on a web application which needs hibernate for DB integration. So i decided to use hibernate with spring. As we all know that Spring is very lightweight and supports hibernate in an easy way. Also i am used to spring JdbcDaoSupport for DB integration and StoredProcedure class for SQL Server stored procedures.

While working this time i decided to use HibernateDaoSupport. Your DAO class must extend this class to use HibernateTemplate class.

Steps to make DAO using this,

- Extend HibernateDaoSupport and also an interface if you have.
- Define your methods which provides different Database operations (CREATE, DELETE, FETCH, UPDATE, INSERT etc...)
- Define required beans as below,

 <bean id="dataSource"  
 class="org.apache.commons.dbcp.BasicDataSource">  
  <property name="driverClassName">  
   <value>com.mysql.jdbc.Driver</value>  
  </property>  
  <property name="url">  
   <value>jdbc:mysql://localhost/testdb</value>  
  </property>  
  <property name="username" value="username" />  
  <property name="password" value="passwordforit" />  
  <property name="defaultAutoCommit" value="true" />  
  <property name="defaultTransactionIsolation" value="2" />  
  <property name="maxActive" value="100" />  
  <property name="maxIdle" value="50" />  
  <property name="minIdle" value="50" />  
  <property name="maxWait" value="100" />  
  <property name="initialSize" value="20" />  
 </bean>  
 <!-- Database Property -->  
 <bean id="hibernateProperties"  
 class="org.springframework.beans.factory.config.PropertiesFactoryBean">  
  <property name="properties">  
   <props>  
    <prop key="hibernate.hbm2ddl.auto">update</prop>  
    <prop key="hibernate.dialect">  
    org.hibernate.dialect.MySQLDialect</prop>  
    <prop key="hibernate.show_sql">true</prop>  
    <prop key="hibernate.cache.provider_class">  
    net.sf.ehcache.hibernate.EhCacheProvider</prop>  
   </props>  
  </property>  
 </bean>  
 <!-- Hibernate SessionFactory -->  
 <bean id="sessionFactory"  
 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  <property name="dataSource">  
   <ref local="dataSource" />  
  </property>  
  <property name="hibernateProperties">  
   <ref bean="hibernateProperties" />  
  </property>  
  <!-- OR mapping files. -->  
  <property name="mappingResources">  
   <list>  
    <value>myMapping.hbm.xml</value>  
   </list>  
  </property>  
 </bean>  
 <bean id="MyDAOTarget" class="com.dao.MyDAO">  
  <property name="sessionFactory">  
   <ref bean="sessionFactory" />  
  </property>  
 </bean>  

- Define transactionManager for transaction managment as below,

 <bean id="transactionManager"  
 class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  <property name="dataSource">  
   <ref bean="dataSource" />  
  </property>  
 </bean>  

- Define org.springframework.transaction.interceptor.TransactionProxyFactoryBean as below, which will eventually make proxy bean on the class given in target property.

 <bean id="MyDAO" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
   <property name="transactionManager">   
     <ref bean="transactionManager"/>  
   </property>   
   <property name="target">   
     <ref bean="MyDAOTarget"/>  
   </property>   
   <property name="transactionAttributes">  
     <props>   
       <prop key="insert*">PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>  
       <prop key="update*">PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>   
       <prop key="delete*">PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED</prop>  
       <prop key="find*">PROPAGATION_REQUIRED, ISOLATION_READ_COMMITTED, readOnly</prop>   
     </props>   
   </property>  
 </bean>  


- Use getHibernateTemplate().get(Class entityClass,Serializable id) OR getHibernateTemplate().load(Class entityClass,Serializable id) to load particular enoty from Database.
- Use getHibernateTemplate().find(String queryString,Object value) to find entities using HQL/SQL query.
- Use getHibernateTemplate().delete(), getHibernateTemplate().deleteAll() for removing entities from Database.
- Use getHibernateTemplate().update() OR getHibernateTemplate().saveOrUpdate() for updating/inserting entity in the Database.

It seems so easy right? But no, wait! All these works fine when you have <property name="defaultAutoCommit" value="true" /> . When you change this property to false, all updates to database will not take effect. Because in that case we need to begin and commit transaction form the code.

I have tried using getHibernateTemplate() for update operations but it failed. It doesn't work with transactions. So try as per the following method.

 public void updateMyObj(MyObj myObj) {  
   Session session = getSession(true);// true means allow create new session if required.  
   Transaction trans = session.beginTransaction();  
   session.saveOrUpdate(myObj);  
   trans.commit();  
 }  

Same thing works for any update operation. This is really strange, i tried for one whole day using getHibernateTemplate() but it never worked with <property name="defaultAutoCommit" value="false" />.

Thursday, May 27, 2010

Java Wildcards Vs. Generics...

I have never used wildcards in java until i read this.

Let's say I have a super class Vehicle and few sub classes like Scooter, Bike, Car, etc... Now I need to have a list of vehicles, my first thought would be something like:

 List<Vehicle> lstVehicles;

Instead, some people are recommending something like:

 List<? extends Vehicle> lstVehicles;

Why should I use wildcards instead of simple generics?

Because Java generics are invariant.

Suppose we have B extends A:

* B is a subtype of A
* an instanceof B is also an instanceof A

Since Java arrays are covariant:

* B[] is a subtype of A[]
* an instanceof B[] is also an instanceof A[]

However, Java generics are invariant:

* List<B> is NOT a subtype of List<A>
* a instanceof List<B> is NOT an instanceof List<A>.

Wildcards are used to make it more flexible while preserving type safety.

*
List<B> is a List<? extends A> 

References:
Wildcards
Generics
Generics and subtyping
More fun with wildcards

Friday, May 21, 2010

Java String manipulation: Appending empty string to 'var.subString(x,y)' saves memory...


In java usually we do SubString operation as follows.


    String strMainData = "Some long String..." ;
    String strSub= strMainData.subString(i,j); // Where i and j are index values...

This operation will keep the reference to same object strMainData,but only returns smaller string as per the indexes. So it uses same memory as the original String.

We should use it as follows.

    String strSub = new String(strMainData.subString(i,j));
OR

    String strSub = strMainData.subString(i,j) +"";
This will only keep the reference to new smaller String and removes reference to original String variable.



Singleton refactored:Initialization on demand holder idiom...

Hey guys, check this out. I found this while searching around different styles for singleton pattern. It basically provides on demand loading of the instance.

public class Something {
 private Something() {
 } 
 private static class LazyHolder {
  private static final Something INSTANCE = new Something();
 } 
 public static Something getInstance() {
  return LazyHolder.INSTANCE;
 }
}

The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable INSTANCE being initialized by executing the (private) constructor for the outer class Something.

More @ Wiki

Hibernate : One-to-many Parent-Child relationships...

Hibernate is quite good ORM framework. When we need one-to-many relationship in hibernate, we need to take ArrayList or Set. If the structure is kind of tree, then hibernate can perform wired if not properly tweaked.


Basically if you are having some sort of many to one relationships structure from child to parent. In hibernate all depends on mapping. Tweak your mapping, Use One-to-many relationship from parent to child using java.util.Set.


Do not use ArrayList because List is ordered, so hibernate will add extra column for that ordering only.
Also check your lazy property. If you load parent and you have set lazy="false" on its child set property (variable which is of type Set), then all of its children will be loaded from DB which can affect the performance.


Also check 'inverse' property for children. If inverse is true in child table, that means you can manage the child entity separately. Otherwise you have to do that using the parent only.