Hi there,
I'm having problems handling several transactions within the same session.
The transactions are created and managed automatically using Spring annotations, and the session is bound to the current thread as usual.
A typical code example might look like this
Code:
List<User> users = userFinder.getUsers();
for(User user : users){
try{
service.createStatement(user, cal);
}catch(Throwable exc){
log.error("error generating statement for user id: "+user.getId(), exc);
}
}
The purpose is that createStatement() is tried in a separate transaction for each user. In case of an error, the transaction is rolled back, error logged, and the next user is then processed in a new transaction.
The service methods are declared like this:
Code:
@Transactional(readOnly = true)
public List<User> getUsers()
throws AccountingException
and
Code:
@Transactional(rollbackFor=Exception.class)
public void createStatement(User user, Calendar cal)
throws AccountingException
The problem, which you would probably anticipate, is that once getUsers() returns, the session that was used for that transaction is closed. I think this means that each User becomes a transient instance.
If I then try to follow a User association within the createStatement() method I get either LazyInitializationException, or 'QueryException: The collection was unreferenced'.
I have tried to find examples of using several transactions within one session but haven't found any. Also, I would really like to keep the Spring annotational transaction demarcations, as they are quite simple and effective. Does anyone know of a way to do this? Is there a way to open a Session at the top level of code, and keep it open until the end of the last transaction?
Also, I've tried different workarounds, and I thought that Session.lock() would let me bring a transient instance into the current session, with:
session.lock(user, LockMode.NONE);
However this leads to the same type of exceptions as before. What does work is Session.merge(), e.g.
user = (User)session.merge(user);
If anyone could shed some light on these issues I would be much obliged. I am happy to provide more information about the transaction manager etc, but I am hoping that this is a problem that I can solve on the Hibernate level rather than Spring. Please do correct me if I am wrong.
cheers,
/m