Spring 3.1 с Hibernate 4 с пружинной безопасностью 3.1: Как убедиться, что транзакции рекомендуются до весенней безопасности. - PullRequest
1 голос
/ 25 января 2012

В моем 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>

В моем приложенииContext-main.xml у меня есть

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

В моем applicationContext-spring-security.xml у меня есть следующее определение бина

мой сервис mcl.

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);
    }
}

мой МакДао

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

Когда я запускаю приложение, я получаю эту ошибку.

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

Я предполагаю, что это потому, что проверка атрибута config при запуске до вызова web.xml вызывает то, как я могу убедиться, что это сеанс во время запуска приложения?

** попробуйте с советом ниже о добавлении @Transactional, все еще с той же проблемой. ** ** Я использую order = 1 для управления аннотациями и aop 2, поэтому сначала будет иметь место транзакция, но, похоже, она не работает.

1 Ответ

1 голос
/ 25 января 2012

Когда фильтр openSessionInView неактивен, в существующей транзакции должен вызываться getCurrentSession().

Таким образом, чтобы обеспечить создание транзакции, вам также необходимо сделать метод обслуживания @Transactional (илиизмените распространение вашего метода DAO на REQUIRED).

...