How to access hibernate session in Thread? - spring

As Hibernate sessions are not thread-safe, I am not able to get currnet hibernate session through sessionFactory.getCurrentSession();
If I choose sessionFactory.openSession(); it works fine for thread itself but for nested classes[called from the thread] it wont allow me to access same newly opened session[Throws "No Session found for current thread" exception].
I am using Spring 3.1.1 and Hibernate 4.1.3
Is there any way to get the current session in thread?
Or is there any way to access newly opened session to nested classes which are called from the thread?

As you are using Spring and hibernate, you will get current session using sessionFactory.getCurrentSession(); if you are using it in transaction. Otherwise you will get exception with message : No Session found for current thread.
e.g. :
void someDBOperation() {
Session session = sessionFactory.getCurrentSession(); // if not in transaction, exception : No Session found for current thread
// some code
}
#Transactional // use either annotated approach or xml approach for transaction
void someDBOperation() {
Session session = sessionFactory.getCurrentSession(); // you will get session here
// some code
}

Related

Redis spring session bean not updated

I am trying to switch my http session to redis in my spring boot application.
When the first request comes to backend it's being filtered by authentication filter.
One duty of this filter is to populate user session bean with data. The session is succesfully saved to the redis instance at this step, but the delta of changes ( which should include the session bean) is not invoked. I want to point out that with storing session on tomcat the session beans work correctly.
So why session bean populated on OnePerRequest filter is not updated as the delta of session ?
Have you tried the below configuration?
#Configuration
#EnableRedisHttpSession(saveMode = SaveMode.ALWAYS)
public class RedisSessionConfig {
}
Try changing the flush mode to IMMEDIATE, by default it's ON_SAVE which means you explicitly have to save the session or in a managed environment, it happens before the response is serialized (I think).
In src/main/resources/application.properties you could do:
spring.session.redis.flush-mode=immediate
Or using #EnableRedisHttpSession do:
#EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE)

JPA transactional proxy within a thread issue

In my Controller I have injected (#Autowired) this Service, which implements Runnable (I need multi-threading) and I call it like so:
Thread t = new Thread(service);
t.start();
t.join();
Then, in my Service's run() I call this Repository (simple JPARepository), which is injected in Service also with #Autowired:
repository.save(someEntity);
The problem is that it doesn't persist the entity with id=1. The transactional proxy (and Hibernate connection pool) is initialized after the unsuccessful saving of the first entity. After that, it works fine.
Can anyone point me to the right direction with my issue: how to force the Thread to initialize the Hibernate transactional proxy before persisting the first entity?
You should consider to start the thread after Spring context is refreshed. This is safer because all your beans may be in an inconsistent state.
#EventListener(ContextRefreshedEvent.class)
public void handleContextStart() {
// ...
}

Change session ID in Struts2 action [duplicate]

In my Struts application once an user login I need to invalidate the current session and create a new session. I invalidate the session with
getHttpServletRequest().getSession().invalidate();
And I create a new session as
getHttpServletRequest().getSession(true);
The problem here is after above I try to access getSession() it gives the state invalid exception; HttpSession is invalid.
getSession() returns a map where in my action class I implements SessionAware which has the setSession(Map session).
EDIT: Below is the exception
Error creating HttpSession due response is commited to client. You can use the CreateSessionInterceptor or create the HttpSession from your action before the result is rendered to the client: HttpSession is invalid
java.lang.IllegalStateException: HttpSession is invalid
So, what I assume the problem is the Struts getSession() still reference the session which I've invalidated.
How to make the Struts getSession() to reference the new session which I've created?
If you want to access the struts session after you invalidated the servlet session you should update or renew the struts session. For example
SessionMap session = (SessionMap) ActionContext.getContext().getSession();
//invalidate
session.invalidate();
//renew servlet session
session.put("renewServletSession", null);
session.remove("renewServletSession");
//populate the struts session
session.entrySet();
now struts session is ready to use the new servlet session and you ready to reuse the struts session.

Security SessionFixationProtectionStrategy interfering with session scoped beans

I'm using Spring 3.1.1.Release, Security 3.1.0.Release.
I've added login/logout to my web app, however a session scoped bean is not functioning the way it was. The bean is used to connect to a CMS called CMSConnector.
To authenticate users, I implemented an AuthenticationProvider, and in the authenticate() call, I get the session-scoped CMSConnector and call the CMSConnector.login(). If the CMS login fails, it fails the login.
THE PROBLEM -
If the login is success, #predestroy logout() is called immediately after the successful login. I then found it was the SessionFixationProtectionStrategy is invoking the invalidate the previous session and assign it a new session.
session.invalidate();
session = request.getSession(true); // we now have a new session
The invalidate() is calling the #predestroy method on the session-scoped bean.
So I have temporarily removed the the #predestroy annotation leaving the connection not closed. (VERY BAD PRACTICE.)
What is a work around to resolve the issue?
I tried to create a #PostConstruct and put the login process there, but the #PostConstruct doesn't get called when request.getSession(true) is called.
Thanks!
Jason
I think its not the SessionFixationProtectionStrategy but the ConcurrentSessionControlStrategy.
Set max-sessions="-1" for this code snippet
I did not solve my original question, but I implemented a workaround - expire session in the session expire object instead of attached with #predestroy.

DWR + Spring + JPA Session Closed

Background
The application I am working on currently uses Spring + JPA. Everything was working fine before we decided to introduce DWR.
Using DWR I invoke a method on a Service class and it then redirects to the Controller.
try{
return WebContextFactory.get()
.forwardToString("/search.do?searchString=" + searchString);
}catch(...){
}
After this, when the search method is invoked at the DAO, it does not find an pen session.
Session session = (Session) entityManager.getDelegate();
This session here is closed...
I think my changes(of introducing DWR) should not in any way affect the Session creation.
Awaiting inputs.
Shardul.
Issue resolved.
The problem was with the configuration of OpenEntityManagerInViewFilter in the web.xml. It was not intercepting the DWR requests as it was mapped to a
*.do
instead of
/*
Shardul.

Resources