Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate/Spring: getHibernateTemplate().save(...) Freezes/Hangs

I'm using Hibernate and Spring with the DAO pattern (all Hibernate dependencies in a *DAO.java class). I have nine unit tests (JUnit) which create some business objects, save them, and perform operations on them; the objects are in a hash (so I'm reusing the same objects all the time).

My JUnit setup method calls my DAO.deleteAllObjects() method which calls getSession().createSQLQuery("DELETE FROM <tablename>").executeUpdate() for my business object table (just one).

One of my unit tests (#8/9) freezes. I presumed it was a database deadlock, because the Hibernate log file shows my delete statement last. However, debugging showed that it's simply HibernateTemplate.save(someObject) that's freezing. (Eclipse shows that it's freezing on HibernateTemplate.save(Object), line 694.)

Also interesting to note is that running this test by itself (not in the suite of 9 tests) doesn't cause any problems.

How on earth do I troubleshoot and fix this?

Also, I'm using @Entity annotations, if that matters.

Edit: I removed reuse of my business objects (use unique objects in every method) -- didn't make a difference (still freezes).

Edit: This started trickling into other tests, too (can't run more than one test class without getting something freezing)

Edit: Breaking the freezing tests into two classes works. I'm going to do that for now, as shamefully un-DRY as it is to have two or more test classes unit-testing the same one business object class.

Transaction configuration:

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

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- the transactional semantics... -->
        <tx:attributes>
            <!-- all methods starting with 'get' are read-only -->
            <tx:method name="get*" read-only="true" />
            <tx:method name="find*" read-only="true" />
            <!-- other methods use the default transaction settings (see below) -->
            <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <!-- my bean which is exhibiting the hanging behavior -->
    <aop:config>
    <aop:pointcut id="beanNameHere"
        expression="execution(* com.blah.blah.IMyDAO.*(..))" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="beanNameHere" />
</aop:config>
like image 798
ashes999 Avatar asked Nov 06 '22 04:11

ashes999


2 Answers

When the freeze happens break the application, find the main thread and capture the stacktrace. Poke through until you find exactly what DB query is running that is blocking in the DB.

You mention running the test on it's own works ok but running the full suite causes a problem. If this is the case then I would guess that one of the prior tests still has a transaction open and has locks on some rows which the blocking test is trying to access.

Do your tests run concurrently? If so stop doing that as they could interfere with each other.

Turn on hibernate.show_sql option so you can see in the console all the SQL being generated.

At the point the freeze happens can you find out which rows are locked in the DB. e.g. in SQLServer you can run sp_lock to see this and sp_who to see which SQL process ids are blocking on another.

like image 175
Mike Q Avatar answered Nov 09 '22 04:11

Mike Q


A few things to check:

  • proper transaction management - it appears that in your configuration you have transactions over a DAO of yours. Generally it is advisable to have transactions around your service layer, and not the DAO. But anyway - make sure you have a transaction around the dao in use by the test. Or make the test @Transactional (if using spring's junit runner)

  • change the logging treshold to info for the datasource (c3p0, perhaps?). It reports deadlocks.

  • watch the database logs for deadlocks (if there is such option)

like image 22
Bozho Avatar answered Nov 09 '22 03:11

Bozho