1

im working on an existing system and need to have my spring transaction manager attach to a thread thats being spawned off of a master job thread. i keep getting this exception

org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63)
    at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
    at parity.model.datamapping.RefreshTask.execute(RefreshTask.java:95)
    at com.paritysys.tasks.ASyncTask$1.run(ASyncTask.java:48)
    at java.lang.Thread.run(Thread.java:662)

ive annotated everything i can think of with the transactional annotation and i still cant get this error to clear.

what am i missing

my method

@TransactionAS400
    @TransactionScores
    public void refresh() {
        ASyncTaskWorker worker = new ASyncTaskWorker() {
            public void progress(double percentage, String message) {
                logger.debug(String.format("%.2f - %s", percentage, message));
            }

            public void handleException(Throwable e) {
                try {
                    status.allowUpdating(property.getSchema());
                } catch (Exception b) {
                    // consume
                }

                logger.error("Failed to complete the refresh task", e);
            }

            public void done(boolean success) {
                status.allowUpdating(property.getSchema());
                logger.debug(String.format(
                        "Reset updating status to default for %s",
                        property.getSchema()));
            }
        };
        RefreshTask refTask = ServiceProviderContext.find(RefreshTask.class);

        refTask.init(property, worker);

        ASyncTaskHandler.getInstance().add(refTask);
        ASyncTaskHandler.getInstance().process();
    }
matt b
  • 138,234
  • 66
  • 282
  • 345
scphantm
  • 4,293
  • 8
  • 43
  • 77
  • May you should post the code that starts the transaction, as well as the code that invoke it. – Ralph Oct 27 '11 at 11:40
  • well, there is no code that starts the transaction. thats what the transactional annotation does inside of my spring bean. my problem seems to be that when the bean is spawned into a new thread for some reason it doesn't realize that spring can start a new transaction in the new thread. – scphantm Oct 27 '11 at 11:54
  • 1
    I expected that you use `@Transactional`. But please post the code that invokes this annotated method. – Ralph Oct 27 '11 at 12:10
  • I was actually interested in the same question ([How to propagate Spring transaction to another thread](http://stackoverflow.com/questions/5232351)). That is actually the Spring ideology, so we have to agree with it... – dma_k Oct 27 '11 at 16:01

2 Answers2

2

I ran into similar situations where I have a thread out of Spring's aspects reach. What I suggest is the following: Define and wire an instance of a org.springframework.transaction.support.TransactionTemplate and then use:

transactionTemplate.execute(new TransactionCallback() {
    @Override
    public Object doInTransaction(TransactionStatus status) {
        //your code
    }
}

I'd recommend calling transactionTemplate.setName("myTransactionsName") beforehand for debugging issues.

daniel_or_else
  • 658
  • 6
  • 11
0

While a TransactionTemplate as suggested in another answer would work fine, there are two other options to be aware of:

1) Define the method as @Transactional (I'm not sure where those other annotations you are using are coming from) and <tx:annotation-driven> or declare a DefaultAdvisorAutoProxyCreator bean

2) Define transactions with <tx:advice> and pointcuts.

Both are documented in the Spring manual.

matt b
  • 138,234
  • 66
  • 282
  • 345