How to get a hibernate session inside a hibernate interceptor?

How to get a hibernate session inside a hibernate interceptor?

I am trying to use Hibernate to ensure transparency of data access through an organization identifier. I set a global filter to filter all requests by organization ID. Now I need to use the Entity interceptor to set the organization identifier for all objects before saving / updating.

Organization ID comes from HttpSession

I set Organizational Id as the Filter property in the Hibernate session that I want to get inside my interceptor, as well as for all attachments and updates. The problem is that I don't seem to have access to the session inside the Interceptor. Any workarounds for this?

+6
java orm hibernate
source share
4 answers

You can, but I would use a simple POJO just to keep things clean. Keep in mind that the value stored in singleton will only be accessible by the same thread that processed the servlet request, so if you do any asynchronous processing, you will need to consider this. Here's a super basic impl:

public class OrgId { public static ThreadLocal<Integer> orgId = new ThreadLocal<Integer>(); } 

Since the organizational identifier is in the session, you can set the ThreadLocal value in an early servlet filter like this (not many errors):

 public class OrgIdFilter implements Filter { public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws java.io.IOException, javax.servlet.ServletException { int orgId = 0; HttpServletRequest req = (HttpServletRequest) servletRequest; HttpSession session = req.getSession(); orgId = Integer.parseInt(session.getAttribute("OrganizationalIdAttr")); try { OrgId.orgId.set(orgId); filterChain.doFilter(servletRequest, servletresponse); } finally { OrgId.orgId.set(null); // Important to clear after request !! } } } 

This assumes that orgId is in session when the filter is called, but if not, you get the idea ....

Then in your interceptor (or almost anywhere) you can get the current orgId stream with:

 OrgId.orgId.get(); // Might be null..... 

The potential snafu here is that all of these components (filter, OrgId and interceptor) must be loaded by the same class loader to ensure that the OrgId class is effectively a singleon, otherwise with multiple ThreadLocal instances hanging around it will not work sequentially or in general. Needless to say, all this must happen in the same virtual machine.

I'm not sure if this is the cleanest way to solve this problem, but it really gives you your orgId where you need it.

+2
source share

If you only need an organizational identifier, you can put it in a static ThreadLocal and then access it in an interceptor.

On the other hand, if you are configured to receive a session, and it depends on your environment, you can intercept the interceptor and use org.hibernate.event.FlushEntityEventListener , which seems to be more appropriate for what you need anyway, you can get session as follows (rough pseudo-code):

 FlushEntityEventListener.onFlushEntity(FlushEntityEvent event) EntityEvent entityEvent = event.getEntityEntry(); EntityPersister persister = entityEvent.getPersister(); SessionFactoryImplementor sessionFactoryImplor = persister.getFactory(); Session session = sessionFactoryImplor.getCurrentSession(); 

From Hibernate 3 On Line Docs : The event system can be used optionally or as a replacement for interceptors.

+2
source share

When you create your Interceptor, if you can provide it with a link to SessionFactory, you can use SessionFactory # getCurrentSession

+2
source share

Interceptor can be made BeanFactoryAware and SessionFactory can be obtained using bean factory, from which you can get the current session.

Since this seemed like a poor design due to circular dependency and turning the Interceptor into a Spring container, I used ThreadLocal as suggested by Nicholas

0
source share

All Articles