So should you still use Spring's HibernateTemplate and/or JpaTemplate??

I was reading an article by Vigil Bose on TSS the other day and saw the usage of the HibernateDaoSupport class. Since this is no longer a recommended way of using Hibernate from Spring, I thought I might as well just blog about it another time.
With the advent of Spring 2.0, it has become possible to start using the Hibernate Session API directly again. The question is whether or not it is wise to abandon the use of the HibernateTemplate when working with Hibernate, or any other template-based approaches Spring features.
Using Spring XxxTemplates
In Spring 1.0, we introduced a revolutionary way of working with data access APIs that threw checked exceptions. The template approach Spring features along with its transaction synchronization manager and the extensive use of runtime exceptions makes any TCFTC (short for try/catch-finally-try/catch as we coined it back in 2005) often found in data access code entirely obsolete. Below you can see (a simplified version and not entirely precise version of) what Spring's template approach does for you (with specific code snippets that you would otherwise have to write).

Acquisition of connection: If transaction synchronization is active (which it is, if you're using Spring's transaction management infrastructure), most of the times any of the Spring templates are using the same connection across the entire thread (things are actually a bit more complicated than that, but that would lead us too much into the gory details).
Participation in a transaction Again, when using transaction management features, Spring will automatically associated any new connection with the current transaction. This again, all depends on the current propagations settings and so on, but whichever way you look at it, your core code is not affected by it.
Specification of the SQL: This is what you (obviously) have to do yourself. The SQL ideally uses bind parameters, to avoid any chances of SQL injection from happening. Parameters are passed to the JDBC template as arguments.
Creation / execution of statement and iterating over result set: After you've specified the SQL, Spring is going to create the statement for you, set any parameters you may have specified, execute it and loop over the result set for you.
Parse result from result set: You can opt for parsing the result set yourself if you like (or if you have complex parsing requirements), or you can have Spring result a list of primitives, or just one value from the result set.
Handling and translation of exceptions: This is where Spring translates any exceptions that might have occurred to Spring's own DataAccessException hierarchy, automatically insulating calling code from the data access technology in use.
Releasing of connection: This is the last piece of the puzzle where Spring releases any resources used. Of course, if transaction synchronization is active, the resources might not be released immediately.
Templates are available for several APIs such as:
- JDBC (JdbcTemplate)
- Hibernate (HibernateTemplate)
- iBatis (SqlMapClientTemplate)
- JDO (JdoTemplate)
- TopLink (TopLinkTemplate)
- Messaging (JmsTempate)
- Transaction management (TransactionTemplate)
- JNDI (JndiTemplate)
Are templates really necessary?
The templates add a lot of value when using an API that uses checked exceptions (as opposed to runtime exceptions or unchecked exceptions), but also add a lot of consistency to your code base. People having learnt Spring's JdbcTemplate can pretty easily start using Spring's JdoTemplate or Spring's HibernateTemplate–the approach to using those is similar for each one of them.
The most visible impact of the Spring template approach is the code reduction for for example JDBC. This is primarily because the checked exceptions are translated to runtime exceptions inside the template, removing the need to catch the exception in your mainline code. Other reasons are the transparent resource management and automatic synchronization with the currently running transaction. Of course it's fairly easy to change a framework to use runtime exceptions natively instead of Spring having to do this and this is what for example Hibernate has started to do from version 3.0 onwards. Hibernate is not the only technology to do this–the Java Persistence API is also using runtime exceptions.
The fact that these technologies are using runtime exceptions essentially renders the Spring template equivalent for those technologies useless… at least largely, and if you're looking at it from a code simplification standpoint. If you are using the Spring HibernateTemplate purely to reduce the amount of code needed to perform Hibernate data access operations, you would say you do not necessarily have to use a template! When looking at the above table however, we can see Spring does a lot more work behind the scenes than you might think.
Apart from partial simplification of the error handling concern (we still have to do translation of exceptions specific to the data access technology to Spring's DataAccessExceptions) the transaction management and resource management concerns are also addressed, by several changes in the underlying data access technologies. Let's look at those in more detail:
Resource management
Since Hibernate 3.0.1 (and in the Java Persistence API from the moment it was first released) it became possible for Spring to manage the underlying resource without you having to go through any of the templates that are available for those technologies. This means that even if you are using the Hibernate API directly (for example through SessionFactory.getCurrentSession()), you will still be using a Spring-managed Hibernate Session. The same holds for an EntityManager obtained through a JPA EntityManagerFactory. This is another reason why you don't have to use Spring's HibernateTemplate anymore to get an integrated experience.
Transaction management
Now that Spring is capable of handling the underlying resources for you without you having to go through the template, Spring will also be able to synchronize the resources with any transaction going on while acquiring the resource. This means the transaction management concern is also addressed without you having to go through a template. Again, this means we do not necessarily have to use Spring's HibernateTemplate anymore.
Error handling
The one and only thing that is not available directly when you are using the plain APIs that come with Hibernate or JPA (i.e. the Hibernate Session or the JPA EntityManager) is the exception translation of technology-specific data access exceptions into the Spring DataAccessException hierarchy. This we can address very easily however as we'll see in a minute.
Going template-less
So, what do things look like if we're not using the HibernateTemplate for example? It's fairly simple to show how things work. The first thing we do is start using Session API directly instead of the HibernateTemplate. To get access to the Hibernate Session we need the SessionFactory which will be injected as usual:
private SessionFactory factory;
public HibernateAccountRepository(SessionFactory factory) {
this.factory = factory;
}
public Account loadAccount(String username) {
return (Account)factory.getCurrentSession()
.createQuery("from Account acc where acc.name = :name")
.setParameter("name", "Alef").uniqueResult();
}
}
The following is the XML that we'll use to assemble the application. As you can see, we're of course still using the Spring way of setting up Hibernate (using the LocalSessionFactoryBean).
<!– the works –>
</bean>
<bean id="accountRepo" class="com.mycompany.HibernateAccountRepository">
<constructor-arg ref="sessionFactory"/>
</bean>
Now, as I said before, because of a small change in Hibernate 3.0.1, Spring is able to manage the Hibernate session for you, without you having to go through the Hibernate session. The one thing that was missing was the exception translation. To also get that going, you only need to annotate the repository with the @Repository annotation (provided by Spring) and turn on exception translation using a post processor.
public class HibernateAccountRepository implements AccountRepository {
// see above for full impl…
}
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
The post processor will automatically recognize the @Repository annotation and issue Spring to turn on exception translation for this bean. The fact that this works using a proxy is not really relevant to the discussion.
Note that the same holds for repositories using the Java Persistence API (JPA). In fact, you don't even need to change the post processor or the annotation at all.
If you are using Hibernate in an environment where annotations are not available (pre Java5), you can still enjoy automatic exception translation; using AOP. First declare an exception translator and then declare a piece of AOP configuration, like so:
class=“org.springframework.dao.support.PersistenceExceptionTranslationInterceptor�/>
<aop:config>
<aop:advisor pointcut=“execution(* *..*Repository+.*(..))�
advice-ref=“persistenceExceptionInterceptor� />
</aop:config>
This pointcut here matches any class implement a Repository interface (more precisely, an interface ending with Repository).
The real question is: which approach to choose??
To answer with a typical consultant's answer: 'it all depends' :). Let me tell you that I personally prefer to work without the HibernateTemplate and the JpaTemplate, just because I think they do not offer enough value anymore. For consistency purposes you could argue that opting for an approach based on templates all across the board gets you to a situation that is similar in all places though; you still have to learn how Hibernate works however and for more complex situations, you might want to go with using the Session API directly anyway. Note that this is still possible if you're using the HibernateTemplate (through Spring's HibernateCallback).
So in short (as the JavaDoc for HibernateTemplate and JpaTemplate already mention) I'd recommend you to start using the Session and/or EntityManager API directly if you're starting to use Hibernate or JPA respectively on a new project–remember: Spring tries to be non-invasive, this is another great example!
[update: minor typos]
[update: added information about annotation-less exception translation]
Shoaib Akhtar says:
Added on June 26th, 2007 at 2:16 pmHi,
Thanks for great article. Just wanted to know that if I am using the the direct Hibernate session , do i need to close the session. I am talking about this code.
public Account loadAccount(String username) {
return (Account)factory.getCurrentSession()
.createQuery("from Account acc where acc.name = :name")
.setParameter("name", "Alef").uniqueResult();
}
So no need to close the session right? and can you enlighten us how Spring actually manages to do that (the inner details and hwo it becomes possible) the other thing that I want to know is that does Spring supports the Extended Persistance Contect rather than single session per request.
Thanks,
Shaoib
Alef Arendsen says:
Added on June 26th, 2007 at 2:44 pmHi Shaoib,
thanks. There is no need to close the session; Spring will automatically do this for you. When you call SessionFactory.getCurrentSession(), you are actually calling into a Spring proxy instead of Hibernate directly. Spring internally uses the TransactionSynchronizationManager, which keeps track of any thread-bound resources (such as the Hibernate Session). Sessions that are left open, are closed at the same time the transaction commits.
Spring does support the extended persistence context, but you have to manage the entity manager yourself. For more information, have a look at the following thread: http://forum.springframework.org/showthread.php?t=27430
regards,
Alef
Shoaib Akhtar says:
Added on June 26th, 2007 at 2:57 pmHi Alef,
Thanks for the quick reply. I viewed the forum thread but the important post teh last one is till unanswered.
Anshu Mishra says:
Added on June 26th, 2007 at 3:05 pmNice article !
Thanks for the post.
Shoaib Akhtar says:
Added on June 26th, 2007 at 3:21 pmHi Alef,
Me again :). I saw the Spring Documentation (the current one) and in the following section
12.2.5. Implementing DAOs based on plain Hibernate3 API
I have not seen any mention of @Repository // from org.springframework.stereotype
and
for the exception translator. Why?? Whats the correct way then and is docs need update there?
Regards,
Shoaib
Daniel Fernández Garrido says:
Added on June 26th, 2007 at 4:10 pmThanks Alef, very well-explained article. Finally I understand what that phrase in the javadoc of HibernateTemplate was about…
If only that tiny code example containing the use of getCurrentSession() and the absence of a Session.close() call was added to that javadoc, in my opinion, it would be much much easier to understand why we should consider not using the template….
Thank you again,
Daniel.
Hani Suleiman says:
Added on June 26th, 2007 at 6:09 pmGreat post, and a shining example of why Spring is as ubiquitous as it is, you dont often see a vendor article telling you to avoid their APIs and remain neutral!
Vigil Bose says:
Added on June 26th, 2007 at 8:46 pmThanks Alef. Your article is a very good pointer to using a simple API without the templates for Data access particularly when using Hibernate or JPA.
Shoaib Akhtar says:
Added on June 26th, 2007 at 8:56 pmHi Alef,
Me again!!!. The post you mentioned regarding the Extended Persistence context is not complete IMHO and the docs are definitely not clear about it as well.
Secondly in Spring docs about the usage of plain Hibernate3 Api http://static.springframework.org/spring/docs/2.0.x/reference/orm.html#orm-hibernate-straight
there is no mention of @Repository // from org.springframework.stereotype as well as
Why? are docs outdated or do they need improvements?
Thanks,
Shoaib
Shoaib Akhtar says:
Added on June 26th, 2007 at 8:58 pmHi Alef,
Me again!!!. The post you mentioned regarding the Extended Persistence context is not complete IMHO and the docs are definitely not clear about it as well.
Secondly in Spring docs about the usage of plain Hibernate3 Api http://static.springframework.org/spring/docs/2.0.x/reference/orm.html#orm-hibernate-straight
there is no mention of @Repository // from org.springframework.stereotype as well as
Why? are docs outdated or do they need improvements?
Thanks,
Shoaib
Rick Evans says:
Added on June 27th, 2007 at 1:16 amHi Shoaib
[quote post="201"]Why? are docs outdated or do they need improvements?[/quote]
Fair point, the docs are incomplete in those areas. I have raised a JIRA issue to address this, and will sort in the next few days.
http://opensource.atlassian.com/projects/spring/browse/SPR-3623
Cheers
Rick
åŠ ç›Ÿè¿žé”? says:
Added on June 27th, 2007 at 1:49 amâ€œæ‹›å•†åŠ ç›Ÿè¿žé”?网â€?是商机在线旗下的自主产å“?çº¿ï¼Œæ˜¯åŠ ç›Ÿè¿žé”?è¡Œä¸šä¸æœ€ä¸“业ã€?最全é?¢çš„的招商信æ?¯å¹³å?°,ä¸ºåŠ ç›Ÿè€…æ??供项目é½?å…¨ã€?涵盖é?¢å¹¿ã€?è¿?è?¥è§„范ã€?诚实å?¯é? çš„æ‹›å•†åŠ ç›Ÿä¿¡æ?¯å?‘布平å?°ã€‚å•†æœºåœ¨çº¿â€œæ‹›å•†åŠ ç›Ÿè¿žé”?网â€?致力于为ä¸å›½å¹¿å¤§çš„æŠ•资创业者,特别是ä¸å°?投资创业者æ??供投资项目ã€?投资指导ã€?创业交æµ?ç‰å…¨é?¢çš„æœ?务。
Bassem says:
Added on June 27th, 2007 at 2:11 amWhat about OpenSessionInViewFilter, will it still work ??
thx
Xavier says:
Added on June 27th, 2007 at 2:45 amI really think the PersistenceExceptionTranslationPostProcessor should allow a more flexible strategy than solely relying on annotations (@Repository by default) to determine which beans it should process. Of course, you could have an annotation strategy… but you could also have other strategies like postprocessing beans that implement a particular interface (IRepository) or extend a particular class (AbstractRepository). That way, developpers who are still stuck with jdk1.4 could use this postprecossor with their own strategy.
Alef Arendsen (blog author) says:
Added on June 27th, 2007 at 3:13 amXavier,
I remember Colin brought this up about a year ago as a possible option to improve support for JDK 1.4. It never made it to the final version however, I can\\\'t recall why exactly. There is a possibility to plug in your own annotation type, via the repositoryAnnotationType property. If you can\\\'t use annotations, you can always use an aspect to get the same behavior going. It\\\'s a little less convenient (it\\\'s impossible to enable it using a single line of code), but it\\\'s still all declarative.
WARNING: untested code (and with the wrong brackets–I can\\\'t get the XML to work in comments)
[aop:config]
[aop:aspect ref=\\\"sessionFactory\\\"]
[aop:pointcut id=\\\"repositoryOperation\\\" expression=\\\"execution(* com.mycorp.dao.* .*(..))\\\"/]
[aop:after-throwing throwing=\\\"ex\\\" pointcut-ref=\\\"repositoryOperation\\\" method=\\\"translateExceptionIfPossible\\\"/]
[/aop:aspect]
[/aop:config]
The advice here by the way is the translateExceptionIfPossible method on the Hibernate SessionFactory. If you are using a different persistence strategy, you have to check for a class implementing the PersistenceExceptionTranslator and plug that in.
[this is outdated: the blog entry itself now contains a way to translate exceptions even in a pre-Java5 environment]
Alef Arendsen (blog author) says:
Added on June 27th, 2007 at 7:58 amBassem,
I wouldn't know why it wouldn't work. The session management strategy used behind the scenes is in fact the same as is used in the HibernateTemplate, so if OSIV works with HibernateTemplate, it should definitely also work when not using HibernateTemplate.
regards,
Alef
Ben Hale (blog author) says:
Added on June 27th, 2007 at 8:08 amAlef is absolutely right that the OSIV behavior continues to work. Basically in Spring 2.0 we wrap the SessionFactory in a proxy that looks up the current session from our well known location (in 2.1 we use the Hibernate facility for this, requiring Hibernate 3.1 ). So as long as you aren't managing sessions yourself (opening and closing), Spring's transaction management and OSIV support work just fine.
Mike Miller says:
Added on June 27th, 2007 at 9:07 amGreat article. I don't want to side-track your blog but can you suggest a good book on Spring 2.x?
I have read and worked thru both the Developer's Notebook on Spring (Tate/Gehtland) and Hibernate (older books). My current project is not a webapp but I want to get 're-acquainted' with webapps and using Spring/Hibernate.
Rick Evans says:
Added on June 27th, 2007 at 9:15 amHi Mike
No books on Spring 2.x from the Spring team are planned… bit of a shame really. You might want to raise a JIRA issue for that one
Pro Spring 2 is being written by Jan Machacek (co-author of the original Pro Spring), but that is still a good few months away. I believe that the second edition of Spring in Action by Craig Walls (which will cover Spring 2) is just about to be released.
There is always the current Spring reference documentation, which although it suffers from not being edited at all
does keep up to date with the latest Spring 2.0 features as they are added.
Cheers
Rick
Mike Miller says:
Added on June 27th, 2007 at 9:22 amThanks, I appreciate the reply!
s.w.pollux says:
Added on June 27th, 2007 at 9:37 amIs there a clerical error in the xml file?
maybe
s.w.pollux says:
Added on June 27th, 2007 at 9:39 ambean id="accountRepo" class="com.mycompany.AccountRepository"
maybe bean id="accountRepo" class="com.mycompany.HibernateAccountRepository "
right?
Alef Arendsen (blog author) says:
Added on June 27th, 2007 at 9:46 am[quote comment="30499"]bean id="accountRepo" class="com.mycompany.AccountRepository"
maybe bean id="accountRepo" class="com.mycompany.HibernateAccountRepository "
right?[/quote]
thanks for spotting this. I've just fixed it in the post.
s.w.pollux says:
Added on June 27th, 2007 at 10:03 amyou are welcome!
this is a great article,thanks again!
Twice says:
Added on June 27th, 2007 at 10:35 amI once tried this but reverted back to the template because the template-less code suffered from something like 'no session associated with Transaction context' Exception. I didn't have the time luxury to find out what the real problem was back then. Hopefully it was just a config error somewhere.
f.naka says:
Added on June 28th, 2007 at 1:11 amHi Mike
I found 'Building Spring 2 Enterprise Applications'.
I'm expecting.
Xavier says:
Added on June 28th, 2007 at 7:57 amI've tried your xml declarative approach but couldn't make it work… Something must be broken with asm because I got the following error:
[...] Caused by: java.lang.AbstractMethodError: org.springframework.core.LocalVariableTableParameterNameDiscoverer$FindMethodParameterNamesClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
at org.objectweb.asm.ClassReader.accept(Unknown Source) [...]
by the way, you should prefix your sessionFactory with an ampersand in the following declaration [aop:aspect ref="sessionFactory"]
Alef Arendsen (blog author) says:
Added on June 28th, 2007 at 8:15 amThanks for pointing that out Xavier…
In the meantime, I've updated the blog entry with a more elegant approach to getting this to work. It doesn't require you to use the session factory anymore directly and the AOP configuration also is a bit simpler.
The problem you're encountered by the way has to do with the dreaded ASM incompatibility issues I've blogged about a couple of weeks ago–it's not related to the exception translation or anything.
Xavier says:
Added on June 28th, 2007 at 8:30 amThis solution is indeed far more simpler! Thanks a lot!
Sylvain Gogel says:
Added on June 28th, 2007 at 9:50 amDoes the bean definition of a transaction manager is required? if no which TX mgr is used?
From my tests it works fine but my test classes (AbstractTransactionalDataSourceSpringContextTests) requires a txMgr… how to test without it?
Andy Jefferson says:
Added on June 28th, 2007 at 11:14 am[quote comment="30318"]you dont often see a vendor article telling you to avoid their APIs and remain neutral![/quote]
Well all of the JPOX docs state explicitly what is a JPOX extension to a standard (JDO or JPA) and that people should avoid them to stay implementation-independent. Just wish other persistence implementations would copy our policy …
Andy Jefferson says:
Added on June 28th, 2007 at 11:17 am[quote]you dont often see a vendor article telling you to avoid their APIs and remain neutral![/quote]
All docs on the JPOX site state explicitly when some feature is an extension to a specification (JDO or JPA) and when something is within spec, advising users to just use core functionality where at all possible to remain implementation-independent. Just wish other persistence implementations would follow our lead …
Colin Sampaleanu (blog author) says:
Added on June 28th, 2007 at 12:12 pmI just wish to clarify a couple of things here:
This technique will actually only work as of Hibernate 3.0.1 with JTA transactions.
Due to enhancements in Hibernate 3.1, it will work in Hibernate 3.1 with any sort of transactions (JTA or local).
Transactions are relevant here because the current session is determined by binding it to the current transaction.
Also, you need to be using Spring 2.0.4 or later to use the PersistenceExceptionTranslationInterceptor and an AOP pointcut to match any arbitrary Interface/Class for your DAOs, as shown at the end of Alef's article. I pestered Juergen at that time to enhance the Interceptor
What it actually does as of 2.0.4 is automatically recognize any sort of resource factory beans like the Spring-wrapped Hibernate SessionFactory (produced by Spring's LocalSessionFactoryBean)a Spring-wrapped EntityManagerFactory, etc., as the exception translators that they also are.
Note when using PersistenceExceptionTranslationPostProcessor that you can customize what annotation it should be looking for. @Repository is just the default. So if you wish to get away from the Spring specific annotation, and use your own, it's quite trivial.
Note also that the AOP Pointcut with PersistenceExceptionTranslationInterceptor can also be used to match any arbitrary annotation (not just a class or interface). The use of the post processor is just a shortcut, but you might prefer the pointcut approach if you are already using Spring AOP anyway.
Colin
Alef Arendsen says:
Added on June 28th, 2007 at 1:22 pm[quote comment="30723"]Does the bean definition of a transaction manager is required? if no which TX mgr is used?
From my tests it works fine but my test classes (AbstractTransactionalDataSourceSpringContextTests) requires a txMgr… how to test without it?[/quote]
Colin's clarification (see above) perfectly answers your question. As he says, it's important to note that transaction management is important here, because it is used to keep track of the Hibernate session.
John says:
Added on June 29th, 2007 at 6:15 amThank you for bringing such nice posts. Your blog is always fascinating to read.
surajz says:
Added on July 5th, 2007 at 10:34 amNice Article !
Thanks
surajz
Timo says:
Added on July 5th, 2007 at 11:20 amHi Alef!
Nice article, thanks!
I have a question, though: AFAIK when using OSIV with singleSession=false I need to configure the HibernateTemplate with setAllowCreate=true to allow my GUI to fetch data outside of transactions. How can I do this using the your approach without the template? I get exceptions saying 'No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here'.
Regards,
Timo
Jörg Heinicke says:
Added on July 6th, 2007 at 3:42 amHi Alef,
there seems to be one thing not addressed by the plain API approach in comparison to the HibernateTemplate: allowCreate. I've set up the template with allowCreate=false to not allow non-transactional sessions. This is handled in SessionFactoryUtils.getSession(SessionFactory, boolean). Without the template it seems I can't prevent non-transactional sessions.
Any ideas?
Regards,
Joerg
Alef Arendsen says:
Added on July 6th, 2007 at 9:58 am[quote comment="32434"]Hi Alef!
I have a question, though: AFAIK when using OSIV with singleSession=false I need to configure the HibernateTemplate with setAllowCreate=true to allow my GUI to fetch data outside of transactions. How can I do this using the your approach without the template? I get exceptions saying 'No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here'.
[/quote]
For singleSession=false Spring will keep any transaction session open until after view rendering. This should not change when you're not using a template anymore. New sessions are not created. So simply execute all of your 'explicit' data access operations inside a transaction and you'll be good. If you're getting the exception you're mentioning above, I think there is a data access operation outside of your transactional boundaries.
Timo says:
Added on July 8th, 2007 at 3:59 amHi Alef!
Thank you for your reply!
[quote comment="32654"][quote comment="32434"]Hi Alef!
I have a question, though: AFAIK when using OSIV with singleSession=false I need to configure the HibernateTemplate with setAllowCreate=true to allow my GUI to fetch data outside of transactions. How can I do this using the your approach without the template? I get exceptions saying 'No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here'.
[/quote]
For singleSession=false Spring will keep any transaction session open until after view rendering. This should not change when you're not using a template anymore. New sessions are not created. So simply execute all of your 'explicit' data access operations inside a transaction and you'll be good. If you're getting the exception you're mentioning above, I think there is a data access operation outside of your transactional boundaries.[/quote]
Yes, I actually do get this exception when executing a data access operation outside of a transaction. But I try to go this route intentionally. If possible, I'd prefer to have most of the GUI initiated DAO read operations run outside of explicit transactions, especially when using the singleSession=false mode. Otherwise I'd end up with eventually many transactions per web-request, which might impact the database.
AFAIK using the HibernateTemplate with setAllowCreate=true I have the option to go that route. But currently I cannot see how to do that with the sessionFactory.getCurrentSession() alternative.
Regards,
Timo
Alef Arendsen says:
Added on July 8th, 2007 at 8:44 amAh okay, I understand[quote comment="32955"]Hi Alef!
AFAIK using the HibernateTemplate with setAllowCreate=true I have the option to go that route. But currently I cannot see how to do that with the sessionFactory.getCurrentSession() alternative.
Regards,
Timo[/quote]
Ah okay, I understand. There no real alternative other than opening and closing the session yourself then. You can of course still use SessionFactoryUtils or use the SessionFactory (instance) directly. Alternatively you could define a point in your program execution where you want to have this session available and one where you're done rendering (typically an interceptor) and open and close a session yourself there.
Alef Arendsen says:
Added on July 8th, 2007 at 8:48 am[quote comment="32597"]Hi Alef,
there seems to be one thing not addressed by the plain API approach in comparison to the HibernateTemplate: allowCreate. I've set up the template with allowCreate=false to not allow non-transactional sessions. This is handled in SessionFactoryUtils.getSession(SessionFactory, boolean). Without the template it seems I can't prevent non-transactional sessions.[/quote]
You're right here. It is not possible to prevent people from opening a session outside a transaction, without resorting to AOP mechanisms for example. Using AOP, you could certainly prevent this from happening. Something like: 'before opening a session, check if a transaction is present' should help.
regards,
Alef
Marvin says:
Added on July 19th, 2007 at 3:17 pmhave any of you encounter problem implementing this solution? here's my case:
I applied this locally using eclipse and dbcp. it runs smoothly.
But when I deploy it in weblogic using jndi, for some reason, the sessionfactory is always null. Even if I re-initialize my sessionfactory using the 'old school' HibernateUtil, when I come back to DAO method, it's being reset to null again. So I end up being an old schooler.
Here's excerpt to my applicationContext:
classpath:hibernate.cfg.xml
Marvin says:
Added on July 22nd, 2007 at 7:17 pm[quote comment="35395"]when I deploy it in weblogic using jndi, for some reason, the sessionfactory is always null.[/quote]
Please disregard. Configuration issue. Sorry. I wanted to remove my post but I cant find the link. Anyway, thanks. –Marvin
Juergen Hoeller (blog author) says:
Added on August 1st, 2007 at 6:10 am[quote comment="32597"]Hi Alef,
there seems to be one thing not addressed by the plain API approach in comparison to the HibernateTemplate: allowCreate. I've set up the template with allowCreate=false to not allow non-transactional sessions. This is handled in SessionFactoryUtils.getSession(SessionFactory, boolean). Without the template it seems I can't prevent non-transactional sessions.[/quote]
Actually, "sessionFactory.getCurrentSession()" will throw an exception when called outside of a managed scope (i.e. in case of no thread-bound Session management being active). So that style can effectively only be used within a transaction and/or an active OpenSessionInViewFilter/Interceptor. This is equivalent to HibernateTemplate's "allowCreate=false" behavior.
Of course people could still call "sessionFactory.openSession()", which will always return a new Session for each call. We could provide a SessionFactory decorator which throws an exception for any "openSession()" call, I guess, with the transaction management code detecting and bypassing that decorator… At least, "openSession()" is a different method; "getCurrentSession()" always has "allowCreate=false" semantics.
Juergen