10

This is a typical setup used in most DAO:

@Transactional
@Repository
public class DAO {

   @Autowired
   SessionFactory sessionFactory;

   public void save(Entity o) {
       sessionFactory.getCurrentSession().save(o);
   }

   public Entity load(int id) {
       return (Entity)sessionFactory.getCurrentSession().get(Entity.class, id);
   }

}

I see only getCurrentSession() called, no openSession or close.

So when I return the entity from load it's not in session, lazy collections cant be loaded. Similarily, save seems to always flush!

Does the @Transactional annotation from spring do the magic of opening and closing sessions AND transactions all by itself?

Binders Lachel
  • 505
  • 1
  • 5
  • 14
  • Yes take a look at this answer http://stackoverflow.com/questions/10680364/how-spring-manage-hibernate-session-lifecycle – Rafik BELDI Jul 12 '14 at 07:38
  • 1
    @ShadowRay hey, thanks. The link is nice, but doesn't relate to `@Transactional`. Are you cabable of describing what happens when u wire a sessionFactory, and then call a method of a DAO? – Binders Lachel Jul 12 '14 at 08:30

2 Answers2

16

In Spring, there is a one-to-one correspondence between the business transaction demarcated by @Transactional, and the hibernate Session.

That is, when a business transaction is begun by invoking a @Transactional method, the hibernate session is created (a TransactionManager may delay the actual creation until the session is first used). Once that method completes, the business transaction is committed or rolled back, which closes the hibernate session.

In your case, this means that invoking a DAO method will begin a new transaction (unless a transaction is already in progress), and exiting the DAO method will end it, which closes the hibernate session, which also flushes it, and commits or rolls back the corresponding hibernate transaction, which in turn commits or rolls back the corresponding JDBC transaction.

As for this being typical use, the hibernate documentation calls this the session-per-operation anti pattern. Likewise, all examples of @Transactional in the spring reference manual are put on business service methods (or classes), not repositories.

sorrymissjackson
  • 2,395
  • 1
  • 19
  • 18
meriton
  • 68,356
  • 14
  • 108
  • 175
5

Spring provide transaction advice to beans which are annotated with @Transactional. Spring transaction provides support for following six attributes which determines the behavior of the transaction

1.isolation , 2.no-rollback-for, 3.propagation, 4.read-only, 5.rollback-for, 6.timeout.

@Transactional can start new transaction or can join existing transactional context based its propagation attribute value.

In @Transactionalcontext, getCurrentSession() method creates new Session object if it does not exist or returns Session which is attached to current transaction. OpenSession() method always creates new session. @Transactional helps you to extend scope of Session.

Session is open first time when getCurrentSession() is executed and it is closed when transaction ends and it is flushed before transaction commits.

In Spring, If we use getCurrentSession() in non-transactional context we get an exception.

Community
  • 1
  • 1
Bhushan
  • 567
  • 2
  • 5
  • 14
  • OK thanks!! So in a `@Transactional` class when I enter a method, a transaction is already in progress right? And it is committed once I leave the method? So, from Hibernate point of view, when I leave the method, the changes do entities are flushed to DB, and entities detached? – Binders Lachel Jul 12 '14 at 13:20
  • No not always. it depends on your propagation mode and isolation level. e.g. PROPAGATION_MANDATORY = Method always starts in transaction if no existing transaction is in progress. By using propagation mode we can run different methods which are @Transaction in one transaction. – Bhushan Jul 12 '14 at 13:30