spring 3.1 with hibernate 4 with spring security 3.1: How do I ensure transactions are adviced before spring security.

StackOverflow https://stackoverflow.com/questions/8997897

Frage

In my web.xml

openSessionInView org.springframework.orm.hibernate4.support.OpenSessionInViewFilter

        <init-param>
            <param-name>singleSession</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>

 <!-- open session in view mapping -->
<filter-mapping>
    <filter-name>openSessionInView</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

In my applicationContext-main.xml i have

 <aop:config>
    <aop:pointcut id="serviceMethods"
        expression="execution(* com.utility.*.*(..))" />
    <aop:advisor advice-ref="ownership.methodSecurityInterceptor"
        pointcut-ref="com.serviceMethods" order="2" />
</aop:config>

In my applicationContext-spring-security.xml i have the following bean define

my mcl service.

public class CustomMethodDefinitionServiceImpl
        implements MethodSecurityMetadataSource {
    private final MclDao mclDao;

    @Autowired(required = true)
    public CustomMethodDefinitionServiceImpl(final MclDao mclDao) {
        super();
        this.mclDao = mclDao;
    }

    @Override
    @Transactional(readOnly=true, propagation=Propagation.REQUIRED)
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return this.getMetaDataSource().getAllConfigAttributes();
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(final Method method, final Class<?> targetClass) {
        return ((MapBasedMethodSecurityMetadataSource) this.getMetaDataSource()).getAttributes(method, targetClass);
    }

    @Override
    public Collection<ConfigAttribute> getAttributes(final Object obj)
            throws IllegalArgumentException {
        return this.getMetaDataSource().getAttributes(obj);
    }

    @Override
    public boolean supports(final Class<?> clazz) {
        return clazz.isInterface();
    }


    public SecurityMetadataSource getMetaDataSource() {
        final List<MethodControlList> methodConrolLists = this.mclDao.getAllMethodControlList();
        final List<ConfigAttribute> configList = new LinkedList<ConfigAttribute>();
        final Map<String, List<ConfigAttribute>> methodMap = new LinkedHashMap<String, List<ConfigAttribute>>();
        for (final MethodControlList mcl : methodConrolLists) {
            final StringBuilder serviceNameBuilder = new StringBuilder();
            final ClassMethod classMethod = mcl.getClassMethod();
            serviceNameBuilder.append(classMethod.getClassName());
            serviceNameBuilder.append(".");
            serviceNameBuilder.append(classMethod.getMethodName());
            final List<Role> roles = this.mclDao.getAllRoleThatCanAccessClassAndMethod(classMethod.getClassName(), classMethod.getMethodName());
            for (final Role role : roles) {
                configList.add(new SecurityConfig(role.getAuthority()));
            }
            methodMap.put(serviceNameBuilder.toString(), configList);
        }
        return new MapBasedMethodSecurityMetadataSource(methodMap);
    }
}

my MclDao

public List<Role> getRolesThatCanAccessClassAndMethod(final String className, final String methodName) {      
     this.sessionFactory.getCurrentSession()
                            .getNamedQuery("getRolesThatCanAccessMethod")
                            .setString("className", className)
                            .setString("methodName", methodName)
                            .list();
}

When I start the application i get this error.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [applicationContext-spring-security.xml]: Invocation of init method failed; nested exception is org.springframework.orm.hibernate4.HibernateSystemException: No Session found for current thread; nested exception is org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor.getAdvice(AbstractBeanFactoryPointcutAdvisor.java:85)
    at org.springframework.aop.aspectj.AspectJProxyUtils.isAspectJAdvice(AspectJProxyUtils.java:67)
    at org.springframework.aop.aspectj.AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(AspectJProxyUtils.java:49)
    at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.extendAdvisors(AspectJAwareAdvisorAutoProxyCreator.java:101)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:68)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359)
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 22 more
Caused by: org.springframework.orm.hibernate4.HibernateSystemException: No Session found for current thread; nested exception is org.hibernate.HibernateException: No Session found for current thread
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:199)
    at org.springframework.orm.hibernate4.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:50)
    at org.springframework.orm.hibernate4.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:37)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy73.getAllMethodControlList(Unknown Source)
    at com.util.security.service.impl.CustomMethodDefinitionServiceImpl.getMetaDataSource(CustomMethodDefinitionServiceImpl.java:63)
    at com.util.security.service.impl.CustomMethodDefinitionServiceImpl.getAllConfigAttributes(CustomMethodDefinitionServiceImpl.java:43)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:137)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
    ... 39 more
Caused by: 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:883)
    at com.util.security.dao.impl.MclDaoHibernateImpl.getAllMethodControlList(MclDaoHibernateImpl.java:88)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    ... 47 more

I am guessing it is because validating the config attribute on startup before web.xml gets invoke, than how would I ensure that their is a session during startup on application?

** try it with advice below of adding @Transactional, still having the same problem. ** ** I use order = 1 for annotation driven and aop 2 so it would have transaction first, but it doesn't seem to work.

War es hilfreich?

Lösung

When openSessionInView filter is not active, getCurrentSession() should be called inside an existing transaction.

So, to ensure creation of transaction you need to make your service method @Transactional as well (or change propagation of your DAO method to REQUIRED).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top