Announcement Announcement Module
Collapse
No announcement yet.
Help newbie with HibernateDaoSupport Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help newbie with HibernateDaoSupport

    Hi,

    we are using Spring and Hibernate on a project (and ehcache for caching), and hope to be able to take advantage of Spring's built-in support for Hibernate.

    For database access we have made a DAO class which extends HibernateDaoSupport.

    Anyway, the problem is that when we try to load about 10,000 objects it takes about 10 seconds, which is too slow for us. If we just use a simple DAO which basically just does this (to load a hierarchy of 10,000 objects starting at the supplied id):
    session = getSessionFactory().openSession();
    obj = session.load( clazz, id );
    then it takes about 1 second.

    Are we using HibernateDaoSupport incorrectly?

    Here is our DAO class:

    public class HibernateDao extends HibernateDaoSupport {
    public Object load(Class clazz, Long id) {
    return getHibernateTemplate().load(clazz, id);
    }

    public void store(Object object) {
    getHibernateTemplate().saveOrUpdate(object);
    }

    public void delete(Object object) {
    getHibernateTemplate().delete(object);
    }
    }

    Thanks,
    Peter

  • #2
    HibernateTemplate.load just delegates to Session.load, so if you are seeing a 10x difference in times, there is something going on. Are you already in a surrounding transaction with thread-bound session? Even if the Session has to be created at that point though, it should not take more than a fraction of a second, not an extra 10 seconds.

    The log is your friend, and should show what is going on. All I can say is that the time for the Spring based code should be identical to the raw code.

    Comment


    • #3
      Hi, thanks for the reply.

      I have looked at the log, but it doesn't really help me that much... I can't identify one specific thing that takes a long time, but there are many sql selects made, and of course the actual writing to the log takes time in itself.

      We are not using transactions ourselves - at least not on purpose yet! (We are only learning Spring/Hibernate, so it is quite possible we have configured something we didn't mean to). We want to use the in-built Hibernate support in Spring because of the transaction management it supplies (that is correct isn't it?).

      The "load" method in HibernateTemplate is like this:

      public Object load(final Class entityClass, final Serializable id) throws DataAccessException {
      return execute(new HibernateCallback() {
      public Object doInHibernate(Session session) throws HibernateException {
      return session.load(entityClass, id);
      }
      });
      }

      Where "execute" is like this:

      public Object execute(HibernateCallback action) throws DataAccessException {
      Session session = (!isAllowCreate() ? SessionFactoryUtils.getSession(getSessionFactory() , false) : SessionFactoryUtils.getSession(getSessionFactory() , getEntityInterceptor(), getJdbcExceptionTranslator()));
      boolean existingTransaction = TransactionSynchronizationManager.hasResource(getS essionFactory());
      if (!existingTransaction && getFlushMode() == FLUSH_NEVER) {
      session.setFlushMode(FlushMode.NEVER);
      }
      try {
      Object result = action.doInHibernate(session);
      flushIfNecessary(session, existingTransaction);
      return result;
      }
      catch (HibernateException ex) {
      throw convertHibernateAccessException(ex);
      }
      catch (SQLException ex) {
      throw convertJdbcAccessException(ex);
      }
      catch (RuntimeException ex) {
      // callback code threw application exception
      throw ex;
      }
      finally {
      SessionFactoryUtils.closeSessionIfNecessary(sessio n, getSessionFactory());
      }
      }

      There is more going on than in the simple DAO code we first used: there seems to be some sort of transaction test, and flushing, ... (and I guess we really should take care of that stuff in our code too).

      If you have any more insights please advise. Otherwise I'll keep digging.

      Thanks,
      Peter

      Comment


      • #4
        Peter,

        You do have to compare apples to apples. If you do not already have a pre-bound hibernate Session (whether because it was created as part of an enclosing transaction, or by any other machanism, for example a nested HibernateTemplate use), then using HibernateTemplate is going to ensure that a new Session is created, and by default, when the template is done you get a flush call. Now that's still not really that different from your case, just the flush is being added (the tests for the transaction and pre-existing session that Spring does will not take any measurable amount of time). If you haven't done any modification of the data, then the flush shouldn't really do anything... But you can certainly try adding the flush to your case, to see if that's it...

        Comment


        • #5
          Originally posted by pak
          Hi, thanks for the reply.


          If you have any more insights please advise. Otherwise I'll keep digging.

          Thanks,
          Peter
          Do you have logging turned on? I had a pull of data that went from about 5 seconds to instant when I turned off hibernate logging using the following
          ##########################################
          # Hibernate #
          ##########################################
          log4j.logger.net.sf.hibernate.impl=ERROR
          log4j.logger.net.sf.hibernate.loader=ERROR
          log4j.logger.net.sf.hibernate.cache=ERROR

          in my log4j properties file.

          Comment

          Working...
          X