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

Wednesday, October 14, 2009

Keep DAO clean using Hibernate Criteria /Criterion

Hibernate Criteria/Criterion classes helps reduce the number of lines in DAO code. Have private methods returning the specific Criterion and in public DAO method compose complex criteria by calling private methods.

public List getSprints(Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
return criteria.list();
}

public List getEntityByType(String type, Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
criteria.add(Restrictions.eq("type", type));
return criteria.list();
}

private Criterion getDateCriteria(Date afterDate, Date beforeDate) {
if(beforeDate == null) { // Is parameter provided ?
beforeDate = new Date();
}
if(afterDate == null) { // Is parameter provided
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
afterDate = cal.getTime();
}

Criterion start = Restrictions.between("startDate", beforeDate, afterDate);
Criterion end = Restrictions.between("endDate", beforeDate, afterDate);
return Restrictions.or(start, end);
}

Keep DAO clean using Hibernate Criteria /Criterion

Hibernate Criteria/Criterion classes helps reduce the number of lines in DAO code. Have private methods returning the specific Criterion and in public DAO method compose complex criteria by calling private methods.

public List getSprints(Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
return criteria.list();
}

public List getEntityByType(String type, Date afterDate, Date beforeDate) {
Criteria criteria = getSession().createCriteria(MyEntity.class);
criteria.add(getDateCriteria(afterDate, beforeDate));
criteria.add(Restrictions.eq("type", type));
return criteria.list();
}

private Criterion getDateCriteria(Date afterDate, Date beforeDate) {
if(beforeDate == null) { // Is parameter provided ?
beforeDate = new Date();
}
if(afterDate == null) { // Is parameter provided
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
afterDate = cal.getTime();
}

Criterion start = Restrictions.between("startDate", beforeDate, afterDate);
Criterion end = Restrictions.between("endDate", beforeDate, afterDate);
return Restrictions.or(start, end);
}

Saturday, December 13, 2008

Hibernate OutOfMemoryException

When working with large number of Hibernate objects returned by a query, hibernate caches these objects in 1st level cache. To avoid running out of heap space use session.flush(), session.clear() and ScrollableResults.

Hibernate Interceptor

Hibernate Interceptor
By implementing Hibernate Interceptor interface or by implementing org.hibernate.classic.Validatable or by implementing org.hibernate.classic.Lifecycle , you can receive the various callbacks from a hibernate "session".

Using these callbacks you could inspect persistent objects before they are saved, deleted, updated or loaded.
    1. Interceptor Approach
    • Interceptor could be done at a session scope or at session factory level or at persistent class level.
      • If its done at session factory level, interceptors must be thread safe, taking care to not store session-specific state since multiple sessions will use this interceptor (potentially) concurrently.
      • At session level, one instance per session.
    • To implement a Interceptor 2 ways
      • Implement interface org.hibernate.Interceptor
      • Or extend org.hibernate.EmptyInterceptor
    • Once interceptor is implemented register it programatically with session or session factory
      • Register the interceptor with Session
Session session = sf.openSession( new MyInterceptor());
      • Register the interceptor with SessionFactory
new Configuration().setInterceptor( new MyInterceptor() );
    • Integration with spring ?



<bean id="myInterceptor" class="com.company.MyInterceptor"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="entityInterceptor">
<ref bean="myInterceptor">
</ref>
</property></bean>
    • Pros & cons
  • Gives flexibility to do things at session and/or at entire application level.
  • Could be a bottleneck if interceptor is being used at SessionFactory level, code inside interceptor has to be written very-2 carefully to make sure it is efficient. --- Things we may end up doing are logging changes to specific database tables in a database or to a log file(files is not a good idea).
  • Would be nice if the interceptors could turned on and off based on configuration files, instead of programatically enabling it.? --- This could be achieved by modifying SPRING configuration file.(applicationContext.xml)
  • To log for specific list of persistence entities there is no out of box configuration, one would have to create additional configuration parameters ?