Spring context refreshing makes Hibernate session throw this exception: No Session found for current thread - spring

I am developing a web application that has multiple spring contexts. It has a main context that holds business logic, hibernate session and application's core needs, and other contexts are for spring mvc binding. Normally application works fine and everything, but when i refresh main context and try to reach hibernate session from other contexts, hibernate session throws this exception:
org.hibernate.HibernateException: No Session found for current thread at
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) at
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:980)...
But funny thing is application can do startup initiation which includes selecting lots of data from db.
Is there a way that i can refresh spring context safe and sound?
P.S: I can get other spring context objects with no problem. And application works fine with multiple contexts until i refresh main context. And i tried refreshing the mvc context, from which i call hibernate session, after main context. Still the same exception in that mvc context.

The reason you are getting that error is that you are whacking the Hibernate sessions out from underneath the threads. The sessions, from what I remember, associated with the Thread that created them. This is why you can't pass a proxied Hibernate entity to frameworks like BlazeDS. As soon as the proxied entity leaves the thread, the session is no long associated with it and you loose the ability to go after the items that are being proxied.
One solution might be to not use Proxies, and eagerly-load all relationships. This would be undermining one of the main benefits of using an ORM, however. Or, if you could somehow re-start all the threads in questions, making new threads that are associated with the new Hibernate session(s), that might work too.

Related

Spring boot app, need to set a database session variable before every transaction

I have a spring boot application that uses Hibernate/JPA entities. I need to run a bit of SQL to set a database session variable prior to each transaction. This session variable controls row level security at the database layer and so the SQL will use a web session parameter which I can retrieve from the spring web session context. I will need this bit of sql to run essentially before every transaction.
I'd like to be able to do this in a way that does not effect every additional piece of business logic. i.e. I'd rather not have to call the method manually from every repository class.
I saw the ConnectionPreparer class in the spring-data-jdbc-ext project (https://github.com/spring-projects/spring-data-jdbc-ext/blob/master/spring-data-jdbc-core/src/main/java/org/springframework/data/jdbc/support/ConnectionPreparer.java). However it appears this class is only called when the connection is first instantiated, not prior to every transaction.

spring-boot-jpa Initial Entity Persistence

I'm trying to figure out how, in the lifecycle of a Spring Boot application, to conditionally persist a single entity when the application starts up. The normal method of loading initial data via 'import.sql' or similar methods is no good in this use case, because the insert is conditional. On start up, I'd like for my application to check and see if an admin account and the associated admin role exists. If neither exists, I'd like the application to create them. If they do exist, I'd like the application to do nothing and leave the existing entities alone. If I use the import.sql method, I'll either wind up with a duplicate key (username=admin) or I'll overwrite the existing admin account, which may have had it's password changed away from the default password by a previous installation of the application.
I've tried using ApplicationListeners for all the default Spring and Spring Boot events, and I get null pointer exceptions for every one of those listeners because the JPA repositories are not yet initialized. I thought that listeners invoked for the ContextRefreshedEvent were supposed to be called after all beans and such are initialized, but I guess I'm wrong about that. I've also tried to create a bean which has a #PostConstruct annotated method which does this entity creation, however I had the same result with the JPA CrudRepositories not being initialized.
So my base question is; "What is the preferred entry point for doing initialization work with JPA CrudRepositories during Spring Boot application start up?"
ContextRefreshedEvent would normally work (so you may have an initialization ordering problem with your listener). You can also use SmartInitializingSingleton or a SmartLifecycle with autostart=true. In a Spring Boot app you also have CommandLineRunner.

Should one close Hibernate Session object every time after performing any CRUD operation?

I am working with enterprise application that uses Spring 3.x with Hibernate annotated programming.I am working with hibernate Session object for performing db operations in my XYZDaoImpl class.
And my doubt is "Is it correct way to close Hibernate Session object every time after performing any CRUD operation?"
If it is not the correct way, please advise me the recommended way of opening/closing of hibernate Session Object.
can you post a bit daoImpl code......
If you use sessionFactory.getCurrentSession(), you will get current session..in this case framework automatically flushed and closed when the transaction ends (commit or rollback).
If you use sessionFactory.openSession(), you have to manage the session yourself and to flush and close it "manually".
No, when using hibernate with spring, you should not (manually) open or close sessions, but let spring manage the hibernate session for you. Spring manages the session as a transactional resource, so you have to configure transaction management correctly.
If you open/close the hibernate session manually, you are hardly using the integration between these two frameworks: the session management is the main feature of the integration.
The only reason to open/close a hibernate session in a spring context is to use the same session to span multiple transactions.

How to reduce database query when using stateless framework like Spring MVC

I just moved to Spring MVC for several days. Before that, I used to develop web project using JSF, EJB and JPA.
In EJB, we can use a stateful session bean(SFSB) with extended persistence context so that I can cache the entities in order to reduce database query. But in Spring MVC, once the entity is returned from a #Service bean, it becomes detached and cannot survive the next request. So I have to query database again in next request.
My question is how can I keep an entity managed by Entitymanager during many request?Thanks!
Use a 2nd level cache or session scoped beans, to keep entities in memory. Spring beans have mulplie different possible scopes.
Worth mentioning that keeping everything stateless makes scaling out easier. And adding state to anything http is always counter intuitive, to me at least.

Should I care about Open Session in View when using Grails?

From my experience of using spring MVC in conjunction with hibernate I know about lazy exception problem occured when addressing to lazy-fetched collection when rendering view.
It pure spring+hibernate world it fixes by introducing OpenSessionInViewInterceptor or OpenSessionInViewFilter thus enabling one hibernate session per request.
So the question is: should I care about this problem in grails or such one-session-per-request behaviour is enabled by default.
If this isn't grails defaults please provide some code to implement this behaviour.
Thanks.
Grails registers a customized subclass of OpenSessionInViewInterceptor (it adds WebFlow awareness). So anything done in the context of a web request will have an open session and lazy-loaded references and collections will resolve.

Resources