hibernate - 帶有 spring 4的3.1,帶有 Spring Security 3.1: 如何確保在 Spring Security 之前事務是 adviced

  显示原文与译文双语对照的内容
0 0

在我的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);
 }
}

我的MclDao


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屬性,而不是在啟動時確保它們是在啟動時的會話。

** 使用下面的建議來嘗試添加 @Transactional,,但仍然有相同的問題。 ** ** 對註釋驅動和 aop 2使用了,= 1,因這裡它會首先處理事務,但它似乎並不起作用。

时间: 原作者:

0 0

openSessionInView 篩選器處於非活動狀態時,應在現有事務中調用 getCurrentSession()

為了確保創建事務,你需要使你的服務方法 @Transactional 同樣是( 或者將DAO方法的傳播更改為 REQUIRED ) 。

原作者:
...