Reputation: 635
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?
Upvotes: 11
Views: 19713
Reputation: 70564
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.
Upvotes: 19
Reputation: 567
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 @Transactional
context, 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.
Upvotes: 5