-->
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.  [ 6 posts ] 
Author Message
 Post subject: get is not valid without active transaction
PostPosted: Wed Jun 25, 2008 10:29 am 
Newbie

Joined: Wed Jun 25, 2008 9:55 am
Posts: 2
Hi, I'm new to Hibernate. Using version 3 and having the following issue-

I'm building out from my data model and running unit tests via JUnit via Ant.
I used the Hibernate tools for eclipse to generate my model classes and DAOs (side question - the tool generated all of the DAOs named PersonHome, AddressHome. Why not PersonDAO, etc?).

When I ran my first unit test, I got the following error:
Code:
No CurrentSessionContext configured!
org.hibernate.HibernateException: No CurrentSessionContext configured!
   at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:542)


So I did a google search and added this line to my hibernate.cfg.xml:
Code:
<property name="current_session_context_class">thread</property>


After that, I got the following error when trying to persist an object:
Code:
persist is not valid without active transaction
org.hibernate.HibernateException: persist is not valid without active transaction
   at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:297)
   at $Proxy0.persist(Unknown Source)


Very well, i suppose that makes sense, an insert is an unsafe operation.

So i began and commited a transaction around my persist as such:
Code:
sessionFactory.getCurrentSession().beginTransaction();
sessionFactory.getCurrentSession().persist(transientInstance);
sessionFactory.getCurrentSession().getTransaction().commit();


Success!, however, I'm now getting the same error when I'm truing to retrieve that very record:
Code:
get is not valid without active transaction
org.hibernate.HibernateException: get is not valid without active transaction
   at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:297)
   at $Proxy0.get(Unknown Source)


So, my questions are:
  • what is a CurrentSessionContext? I supplied the value "thread". what does that mean? What are the other options?
  • I'm guessing that all session operations that access the DB must be part of a transaction? The persist makes sense, but why the get?
  • If, indeed, all operations must explicitly be part of a transaction, then why did the Hibernate tools code generator not put that in my DAO as well?


Sorry for the long post. Thanks for any help!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 25, 2008 11:46 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
# I'm guessing that all session operations that access the DB must be part of a transaction? The persist makes sense, but why the get?

Indeed. This is always true, but sometimes JDBC connectors hide this reality from us.

A transaction is very appropriately defined as a "unit of work." If going to a database and getting data isn't a unit of work, I don't know what is. Of course, people often associate a transaction with ACID properties, and think that a transaction goes hand in hand with a change of data and a possible rollback. But regardless if you are just reading or if you are updating, you're doing work, and that must happen in a transaction.


# If, indeed, all operations must explicitly be part of a transaction, then why did the Hibernate tools code generator not put that in my DAO as well?

Well, doing so would walk you right into the transaction-per-operation anti-pattern. If each update, get, save or delete method starts and stops a transaction, well, then you'd have alot of transactions. Often you want multiple operations to work within a common, rollback-able, transaction. You may want to update one column, delete from another table, and save to a log table, and if any of this fails, you want the ability to roll it all back. If the begin and commit semantics are within the same DAO method, each method call would be atomic, and that's bad.

The Hibernate code manages how the client application marshals calls back and forth to the database layer. However, how transactions are demarcated should be left to the client, so inteligent decisions can be made about how various pieces of data should work together within the scope of a single, ATOMic trasaction.

I have a little tutorial on my website that discusses how Hibernate works which you might find interesting. Check it out.

http://jpa.ezhibernate.com/Javacode/learn.jsp?tutorial=07howhibernateworks

Good questions!

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 25, 2008 2:42 pm 
Newbie

Joined: Wed Jun 25, 2008 9:55 am
Posts: 2
Hi Cameron-
Thanks for your post. I took a look at your site - it's excellent. I will certainly be referencing it more as I go through this project.

I guess what's throwing me off is, as far as I understand the DAO pattern, all details of the transaction should be encapsulated in the DAO itself. It seems that Hibernate suggests otherwise, both by the way the DAOs are generated by the eclipse tool, and in the Hibernate documentation itself. See http://www.hibernate.org/328.html. In all three examples, the controller handles the transaction as well as the manipulation of the DAOs


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 25, 2008 3:14 pm 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Isn't it great when you're mind is exposed to a new way of thinking? And if you think the way we deal with DAOs is interesting, just wait until we blow your mind with the Open-Session-In-View design pattern. :)


Quote:
as far as I understand the DAO pattern, all details of the transaction should be encapsulated in the DAO itself.


Well, I've seen that quite a bit in the past, and I've seen alot of EJB implementations implemented in just this way. But it creates a very large number of transactions, and really handcuffs the developers who are using the DAOs.

What's the point of the DAO? It's really to make it easy for the application developer to interact with back end data, while at the same time, hiding the implementation details. Really, DAOs hide the plumbing that is behind the scenes. But what they shouldn't do is restrict how the data is used. By demarcating transactions behind the DAO methods, you have essentially decided for all of the people using them when a unit of work begins and when it ends. There are often very compelling reasons to have longer transactions, or have multiple DAOs particiapte in transactions. Having a DAO method cut off the transaction as it finishes really takes the power away from but people who will be using them to implement business logic.

Plus, what if your transaction manager changes? A client using the DAO may use a HibernateUtil class to demarcate a transaction, but what if that changes to the J2EE UserTransaction object. The people using the DAOs can decide this. If the transaction details are inside the DAO, the solution becomes much less flexible.

But you are correct - the way Hibernate and Spring and most of the other young show-offs demarcate transactions is outside of the DAO, in the business layer, not the data layer.

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 29, 2008 8:31 am 
Newbie

Joined: Mon May 07, 2007 4:03 am
Posts: 2
Location: India
The problem is with sessionFactory.getCurrentSession()
instead use sessionFactory.openSession()


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 30, 2008 8:02 am 
Expert
Expert

Joined: Tue May 13, 2008 3:42 pm
Posts: 919
Location: Toronto & Ajax Ontario www.hibernatemadeeasy.com
Using openSession is extremely dangerous if you don't know the implications of using an openSession.

openSession is effective if the client application is managing the Hibernate Sessions itself. So, if you have written a program to do your own Hibernate Session management, you're good. But I have only known a few implementations that found this necessary, and conversely, I have many people use openSession without understanding the difference between getSession and openSession, and this has caused many problems.

Use the right tool in the right spot, but you definitely don't want to be opening a new Session every time, unless you have the state management aspect implemented to maintain a reference to those opened Hibernate Sessions.

_________________
Cameron McKenzie - Author of "Hibernate Made Easy" and "What is WebSphere?"
http://www.TheBookOnHibernate.com Check out my 'easy to follow' Hibernate & JPA Tutorials


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

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.