I am trying to enable an hibernate filter using Spring AOP And Spring Boot. I used this post as a starter point:How to enable hibernate filter for sessionFactory.getCurrentSession()?
So far I haven't been able to intercept the Hibernate session:org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession().
My aspect class looks like this:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import com.acme.CustomUserDetails;
@Component
@Aspect
public class ACLFilter {
Logger log = LoggerFactory.getLogger(ACLFilter.class);
@AfterReturning(pointcut = "execution(* org.hibernate.internal.SessionFactoryImpl.openSession(..)))", returning = "session")
public void forceFilter(JoinPoint joinPoint, Object session) {
Session hibernateSession = (Session) session;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
Long userId = ((CustomUserDetails) auth.getDetails()).getUserId();
// Session session = em.unwrap(Session.class);
hibernateSession.enableFilter("groupACL").setParameter("userId", userId);
}
@Before("execution(* org.hibernate.SessionFactory.openSession(..)))")
public void do2(JoinPoint joinPoint) {
System.out.println("############################do2");
}
@Before("execution(* org.hibernate.SessionBuilder.openSession(..)))")
public void do3(JoinPoint joinPoint) {
System.out.println("############################do3");
}
@Before("execution(* org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession(..)))")
public void do4(JoinPoint joinPoint) {
System.out.println("############################do4");
}
}
This is all the classes/methods I tried to intercept. I also validated that the aspect class was working correctly with a test class/method and it does, so the AOP setup is correct. While debugging I can see that the system triggers org.hibernate.internal.SessionFactoryImpl.SessionBuilderImpl.openSession() but doesn't trigger my interceptor? My application.properties file include this entry:
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
What am I missing?
The Hibernate classes are not Spring components, thus Spring AOP does not work for them. If you want to intercept them, I suggest you switch to full AspectJ with load-time weaving. Then you also have a choice not to use execution()
which would manipulate Hibernate's bytecode, but call()
instead which would only change your own classes.