The final answer

This post is part 8 in a 9-part series on Envers, Spring, and JTA. The next post is Blowing up in test mode, and the previous post is An answer.


The story thus far:

The envers beforeCompletion() hook was not running when I switched from using Spring’s HibernateTransactionManager to using its JtaTransactionManager.  I had done some digging on my own, then made a long post to the Spring Data Access forum (after an initial post to the envers forum).

The long post apparently scared everybody off ;) , so I wrote a much shorter, more focused post.

A reply to the shorter post pointed me to the SessionFactoryUtils javadoc, where I read:

Note that for non-Spring JTA transactions, a JTA TransactionManagerLookup has to be specified in the Hibernate configuration.

On the trail of how to specify a TransactionManagerLookup, I found the hibernate.transaction.manager_lookup_class setting in the Using JTA section of the Hibernate Reference Guide — but unbeknownst to me, another setting was needed…

Final Answer

A Hibernate Users forum post titled How can i use JTA with Hibernate? points to the Transaction demarcation with JTA section of the Sessions and transactions Wiki page, where we see:

  • set hibernate.transaction.manager_lookup_class to a lookup strategy for your JEE container
  • set hibernate.transaction.factory_class to org.hibernate.transaction.JTATransactionFactory

So, adding these two lines to my Hibernate spring beans file (lines 6 and 7 below) fixed the issue:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		...
<property name="hibernateProperties">
<props>
				...
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
			</props>
		</property>
		...
    </bean>

NOW the envers beforeCompletion() hook gets called when using the JTA transaction manager.

Whew!

3 thoughts on “The final answer

  1. Hi, i’m trying to use envers, but i can’t even Audit.
    I use @Entity and @Audited in my classes.
    I use envers 1.2.0.ga and hibernate 3.3.1.ga

    This is my config:

    org.hibernate.transaction.JBossTransactionManagerLookup
    org.hibernate.transaction.JTATransactionFactory

    But i get this error:
    Caused by: org.hibernate.HibernateException: Could not locate TransactionManager

  2. I am getting null values for child tables when i do forRevisionsofEntity query

    List revisionList=reader.createQuery().forRevisionsOfEntity(CurrentScheduledMaintenance.class, false, true)
    .add(AuditEntity.relatedId(“property”).eq(propertyId)).getResultList();

    The code in CurrentScheduledMaintenance.class is
    @OneToOne (fetch = FetchType.EAGER)
    @JoinColumn(name = “WORKSTREAM_ID”)
    @ForeignKey(name = “currentmaintenance_workstream_fk”)
    public Workstream getWorkstream() {
    return workstream;

    Please advise the solution

  3. Reseba, Praveen,

    Sorry, I’ve been off this project for several months now and I will not be able to research your questions. I hope the posts on this site chronicling my successes and failures may be of some help to you – otherwise, when you figure it out I would be happy to hear what worked!

    -Daniel-

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.