Reputation: 701
I have the following declaration code:
<tx:advice id="txAdvice" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="Get"/>
<tx:method name="Update"/>
</tx:attributes>
</tx:advice>
I call methods "Get" and "Update" from function "X".
Method "Update" throw exception "Different object with the same identifier value was already associated with the session"
How to close session during Spring after execute method?
Update info:
I will try to describe problem more precisely.
I have mvc project. Conrolers call managers (they represent business logic). Managers use Repositories for interacting with db. At the update action I do the following things:
Each function of the manager is wraped into transaction by AOP. When I call Update method it writes error. Looks that it is because Account object still attached to the session which was opened for Get function. I tried to open and close session directly at the Get function (without AOP). All works correct in that case.
So the question is why Account object still attached to the session after Get call?
Imho you are not using Interfaces for your Repo and spring fails to build the AOP decorator.
I am using interfaces for manager. I tested rollback of the transaction. It works, so i think that AOP decorator is build.
Upvotes: 2
Views: 686
Reputation: 10557
From the comments to your question, I understand that your AOP proxies are correctly configured. I understand you have a manager class like this:
public class Manager : ISomeInterfaceToProxy
{
object Get(...) {}
void Update(object toUpdate) {}
}
This manager class is adviced with the transaction interceptor from your question.
This manager is injected onto your controller, which first calls Get()
(initiating and completing the first transaction) and then Update(...)
. It is important to realize that the call on Update(...)
initiates a second transaction, which might result in the error you mention when the session scope is not "per request". If it does not find a session, each transaction will create new session.
There are several solutions:
Get(...)
and Update(...)
routines from within another method that is wrapped in a transaction advice, such that the transaction is propagated between method callsUpvotes: 2