【问题标题】:spring 3.1 with hibernate 4 with spring security 3.1: How do I ensure transactions are adviced before spring security.spring 3.1 with hibernate 4 with spring security 3.1:如何确保在 spring security 之前建议交易。
【发布时间】:2012-02-18 08:28:03
【问题描述】:

在我的 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>

在我的 applicationContext-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 我有以下 bean 定义

我的 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

我猜这是因为在 web.xml 被调用之前验证启动时的配置属性,而不是我如何确保它们在应用程序启动期间是一个会话?

** 尝试以下添加@Transactional 的建议,仍然遇到同样的问题。 ** ** 我将 order = 1 用于注释驱动和 aop 2,因此它会首先进行事务,但它似乎不起作用。

【问题讨论】:

    标签: hibernate session web-applications spring-aop spring-3


    【解决方案1】:

    openSessionInView 过滤器未激活时,应在现有事务中调用getCurrentSession()

    因此,为确保创建事务,您还需要将服务方法设为 @Transactional(或将 DAO 方法的传播更改为 REQUIRED)。

    【讨论】:

    • 您好,谢谢。我试过了,没有用。我添加了 tx:annotation-driven 并在同一个 xml 中定义了 bean。另外我在 getAllConfigAttributes 前面添加了@Transactional(readOnly=true,propagation=Propagation.REQUIRED)
    • 这加上从 7.0.23 更新到 tomcat 7.0.25 的作品。我需要让 mclDao 成为 mclService。
    猜你喜欢
    • 2012-12-17
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    相关资源
    最近更新 更多