These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Invalid session.getTransaction()?
PostPosted: Mon Oct 10, 2005 10:05 am 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
Hibernate version: 3.1rc1

Full stack trace of any exception that occurs:
Code:
org.hibernate.HibernateException: only beginTransaction() is valid when transaction not yet started
   at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:263)
   at $Proxy4.getTransaction(Unknown Source)
   ...


Why is it invalid to call session.getTransaction() before executing beginTransaction()?
It would be much more useful if getTransaction() returns null, if there is no current transaction.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 10:48 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Why would that be easier? You call beginTransaction() to get a Transaction object and start a transaction at the same time. It does not make much sense to return null or return a Transaction object that isn't already active. The latter might have some uses, we are discussing the asymetry in the API right now. However, "null" is not an option.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 11:33 am 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
I didnt't write "easier" but "more useful".

I've implemented a method-interceptor-based transaction management, where i'd like to know, if the current Session already has an active transaction.

My current implementation uses a ThreadLocal to store the transaction instance (just like the session), but it would be nice if session.getTransaction always returns something useful. Getting an "inactive" Transaction instance instead of null would be equivalent.

Thanks for your quick answer,

heiko


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 11:42 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
The reason it cannot is Serialization of the Session. Transactions, rightfully so, are not serializable. Thus serializing a session with a reference to a transaction will not work.

If you already have a method interceptor approach, what you'd probably want to do instead is to not use the standard ThreadLocalSessionContext, but to implement a custom version. In this custom one, build and bind the sessions from your existing interceptor code.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 12:19 pm 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
Quote:
The reason it cannot is Serialization of the Session. Transactions, rightfully so, are not serializable. Thus serializing a session with a reference to a transaction will not work.

I'm not sure, I understand you correctly, but I don't need to serialize sessions. My app is a J2SE fat client. No appservers or rmi involved.

So what exactly is the use of the session.getTransaction method?

Quote:
If you already have a method interceptor approach, what you'd probably want to do instead is to not use the standard ThreadLocalSessionContext, but to implement a custom version. In this custom one, build and bind the sessions from your existing interceptor code.

Then I can't see any advantage compared to the classic HibernateUtil implementation (plus Transaction-ThreadLocal) I'm using right now.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 2:19 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Did not say *you* needed to serialize sessions. A session is Serializable by contract; whether *you* serialize it or not, it needs to have the capability of being serialized while not connected.

Well, the only real advantage is swap-ability of implementations. When/if you switch over to JTA, it is a simple change of a few config properties in Hibernate versus changes in your code. If that is not an advantage for you, then hey don't use it. Simple, right?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 4:24 pm 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
Ok, got it.

But then I don't see any additional value in this method, when all it does is returning the transaction instance that was already returned by beginTransaction (except for some stylish method chaining).

But hey, I don't have to use it, right? ;-)

Regards,

heiko


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 4:38 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
exactly ;) Personally, I don't see the value of JTA-less transactions; but thats just me...

BTW, if you look at the source for that class, you'll see my comment about making that generated proxy less restrictive. Eventually, there will be a way to determine if there is an existing transaction. Right now other methods are throttled (like isOpen() for example) which also make alot of sense being available here.

http://cvs.sourceforge.net/viewcvs.py/hibernate/Hibernate3/src/org/hibernate/context/ThreadLocalSessionContext.java?rev=1.4&view=auto


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 5:39 pm 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
Quote:
Personally, I don't see the value of JTA-less transactions; but thats just me...

You're right, but unfortunately it is my client's requirement not to use an appserver. I was looking for a standalone TransactionManager and tried jotm/xapool, but had several problems with reliability (closed connections in the pool & crashing cleanup-threads). I refrained from trying out Tyrex because I only read unfavorable comments about it.

Please feel free to suggest an alternative.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 10, 2005 7:12 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
try this

Code:
public Trransaction getTransaction(Session session) {
  Transaction transaction = null;
  try {
     transaction = session.getTransaction();
   } catch(HibernateException e) {
     return null;
    }
    return transaction;
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 6:50 am 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
Sure, that's a trivial solution, but I don't like using a per definition unrecoverable exception as a workaround. As long as there's no elegant way determining the existence of a running transaction, I'll stick with my current solution (tracking the transaction state inside HibernateUtil).

:)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 7:24 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
What would you do if you could "determine the existence of a running transaction"? Not start one? That's what beginTransaction() does internally.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 7:24 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
BTW, I just checked in some changes to allow the call to getTransaction() from one of these proxied Sessions:

Code:
            if ( !realSession.getTransaction().isActive() ) {
               // limit the methods available if no transaction is active
               if ( "beginTransaction".equals( method.getName() )
                     || "getTransaction".equals( method.getName() )
                     || "isTransactionInProgress".equals( method.getName() )
                     || "isOpen".equals( method.getName() ) ) {
                  log.trace( "allowing method [" + method.getName() + "] is non-transacted context" );
               }
               else {
                  throw new HibernateException( method.getName() + " is not valid without active transaction" );
               }
            }


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 7:49 am 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
christian wrote:
What would you do if you could "determine the existence of a running transaction"? Not start one? That's what beginTransaction() does internally.


I would throw a TransactionNotSupportedException if the called method is declared with TransactionAttributeType.NEVER.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 11, 2005 7:55 am 
Beginner
Beginner

Joined: Wed Apr 13, 2005 10:34 am
Posts: 38
steve wrote:
BTW, I just checked in some changes to allow the call to getTransaction() from one of these proxied Sessions:


Thanks!
:)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.