First let make clear.
There are two concepts
OLD WAY: Bound hibernate session to thread. One thread - one session.
NEW WAY. Bound hibernate session to transaction. One transaction - one hibernate session.
If you chose the old way - you are on your own, not gonna advice anything but most common approach create a transaction the same place thread get connected first time to your code (
Servlet, StrutsAction, SpringController, WebService Endpoint - plenty of choices but all driven by a controller framework)
If you chose a new way then you are going to use AOP. You will tell to which classes and methods transactions have to be created. Here I give you few advices
1. Start from defining interfaces. AOP only works with interfaces so if you have a class/method reference that a new transaction should start - not gonna work. Use only interface references.
2. Every DAO method should be able to start transaction by using transaction demarcation (REQUIRED/SUPPORT). You need it for unit testing. Never (Never !) in production transaction shell be started by
direct call to DAO but for running unit tests you have to keep a gate open. So ideally you will have two configurations one for prod, another one for unit testing
3. For every transaction as people above say you have to define an orchestrator. For me it is just a dummy Spring bean that has million of definitions - each invokes a program that implements the same interface.
Pointcut saying my orchestrators need a transaction
And I have a million of beans based on the same orchestrator class
Orchestrator here is just a class that invokes a program that might need a transaction. It validates a form, convert form parameters into domain object and passes them to program that has to handle a request. Spring AOP makes sure that transaction is created and commited/rolled back once orchestration is completed