文档章节

【待解决】SpringMVC+Hibernate4的Session问题

 海岸Thirty
发布于 2017/04/09 17:40
字数 921
阅读 23
收藏 0

写在前面的话:莫名奇妙的问题好了,但是没有按照我的想法来,测试了下最终生效的是

@EnableTransactionManagement。

先看看代码吧,以后有什么突破再更新!或者最好有大神帮我看看吧。

(两次搭项目都这样,哎。。。已经不是人品问题了我觉得)

 

OpenSessionInViewFilter,这个具好用,配置上HTTP就不报下面这个错了

Could not obtain transaction-synchronized Session for current thread

这里给份注解配置吧

/**
 * 所有实现了WebApplicationInitializer接口的类都会在容器启动时自动被加载运行,用@Order注解设定加载顺序
 * 这是servlet3.0+后加入的特性,web.xml中可以不需要配置内容,都硬编码到WebApplicationInitializer的实现类中
  * <ul>
 *  <li>处理URL上下文</li>
 *  <li>定义ServletMapping映射:.do,.json,.jsonp</li>
 *  <li>加载配置文件,相当于引入applicationContext.xml</li>
 * </ul>
 * @author lanxb
 * @create 2016年5月24日
 *
 */
@Order(2)
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	
	/*****  省略无关的内容   *********/
 
    /*
	  * 注册过滤器,映射路径与DispatcherServlet一致,路径不一致的过滤器需要注册到另外的WebApplicationInitializer中
	  */
    @Override
    protected Filter[] getServletFilters() {
        // 请求编码转换
    	CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        
        // OpenSession
        OpenSessionInViewFilter hibernateSessionInViewFilter = new OpenSessionInViewFilter();
        return new Filter[] {characterEncodingFilter,hibernateSessionInViewFilter};
    }
  
  


}

 

因为有一个启动时到数据库加载配置的过程,由于不经过上面的filter,所以一直报错。

    @OpenSession
	@Transactional(readOnly=true)
	@Override
	public void afterPropertiesSet() throws Exception {
		List<AppConf> list = iwxMsgCryptDao.getListByHQL("from AppConf");
		logger.info("refres app configs begin : {}",mapConfig.size());
		if(list==null || list.isEmpty()){
			synchronized (mapConfig) {
				mapConfig.clear();
			}
		}else{
			Map<String,AppConf> mapConfig = new HashMap<>(); 
			for(AppConf conf:list){
				logger.info("\t add app config:{}",conf.getAppId());
				// 生成下keyData
				conf.setAesKey(conf.getAesKey());
				mapConfig.put(conf.getAppId(), conf);
			}
			this.mapConfig = mapConfig;
		}
		logger.info("refres app configs end : {}",mapConfig.size());
	}

于是查了查增加了下面的配置OpenSessionInterceptor:

想通过AspectJ代理带有@OpenSession注解的方法,在执行的时候获取HibernateSession

主要是:

openSessionPointcut()、openSessionInterceptor()然后openSessionAdvisor()、proxyConfig()


@Configuration
@EnableTransactionManagement
public class DBConfig implements TransactionManagementConfigurer{

	final static Logger logger = LoggerFactory.getLogger(DBConfig.class);
	
	@Value("${hibernate.dialect:org.hibernate.dialect.MySQL5Dialect}")
	String hibernate_dialect;
	
	@Value("${jdbc.driver}")  
    String driverClass;  
    @Value("${jdbc.url}")  
    String url;  
    @Value("${jdbc.username}")  
    String userName;  
    @Value("${jdbc.password}")  
    String passWord;
    
    @Value("${jdbc.initialSize:1}") 
    int initialSize=1; 
	//#定义最大连接数  
    @Value("${jdbc.maxActive:20}") 
	int maxActive=20;
	//#定义最大空闲  
    @Value("${jdbc.maxIdle:20}") 
	int maxIdle=20;
	//#定义最小空闲  
    @Value("${jdbc.minIdle:1}") 
	int minIdle=1;
	//#定义最长等待时间  
    @Value("${jdbc.maxWait:60000}") 
	int maxWait=60000;
	
    
    @Bean(name = "dataSource")  
    public DataSource dataSource() {
    	logger.info("初始化数据源开始……\n{}",url);
    	BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(driverClass);  
        dataSource.setUrl(url);  
        dataSource.setUsername(userName);  
        dataSource.setPassword(passWord);  
        dataSource.setInitialSize(initialSize);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxIdle(maxIdle);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        logger.info("初始化数据源结束");
        return dataSource; 
    } 
    
    
    @Bean(name = "sessionFactory")
	public LocalSessionFactoryBean localSessionFactoryBean()  {
		logger.info("sessionFactory");
		LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
		sessionFactory.setDataSource(dataSource());
		String[] packagesToScan = new String[] { "pub.thirty.tbk.module.**.domain" };
		sessionFactory.setPackagesToScan(packagesToScan);
		Properties hibernateProperties = new Properties();
		hibernateProperties.setProperty("hibernate.dialect", hibernate_dialect);
		hibernateProperties.setProperty("connection.autocommit", "false");
		
		hibernateProperties.setProperty(
				"hibernate.current_session_context_class",
				"org.springframework.orm.hibernate4.SpringSessionContext"
		);

		sessionFactory.setHibernateProperties(hibernateProperties);
		return sessionFactory;

	}
    
    @Bean(name = "transactionManager")
	public HibernateTransactionManager hibernateTransactionManager() {
		logger.info("transactionManager");
		HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager();
		hibernateTransactionManager.setSessionFactory(localSessionFactoryBean().getObject());
		hibernateTransactionManager.setNestedTransactionAllowed(true);
		return hibernateTransactionManager;
	}

    
    @Bean
    public Pointcut openSessionPointcut(){
    	AspectJExpressionPointcut bean = new AspectJExpressionPointcut(); 
    	bean.setExpression("@annotation(pub.thirty.tbk.config.annotation.OpenSession)");
    	return bean;
    }
    
    @Bean
    public OpenSessionInterceptor openSessionInterceptor(){
    	OpenSessionInterceptor oi = new OpenSessionInterceptor();
    	oi.setSessionFactory(localSessionFactoryBean().getObject());
    	return oi;
    }
    
    @Bean
    public DefaultPointcutAdvisor openSessionAdvisor(){
    	DefaultPointcutAdvisor bean = new DefaultPointcutAdvisor();
    	bean.setAdvice(openSessionInterceptor());
    	bean.setPointcut(openSessionPointcut());
    	return bean;
    }
    @Bean 
   public ProxyConfig proxyConfig(){
	   AnnotationAwareAspectJAutoProxyCreator bean = new AnnotationAwareAspectJAutoProxyCreator();
	   bean.setProxyTargetClass(true);
	   return bean;
   }
    
	@Override
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return hibernateTransactionManager();
	}
   
}

 

1、目前生效的应该是:

@EnableTransactionManagement

(我的主Config应该时另一个类,这个注解似乎不用写在主Config里,虽然网上有人这么说)

2、OpenSessionInterceptor的想法是通过新建一个针对@OpenSession 切面,

  当调用带有@OpenSession的方法时,openSession或者getCurrentSession();

    bean.setProxyTargetClass(true); 这句时为了指定CGLIB代理,因为方法的接口是InitializingBean,感觉可能代理不到,不知道是不是必须。

PS:奇怪的是上周我加了@EnableTransactionManagement也不起作用,这周写完其他模块,回来重新放开启动模块居然发现神奇的好了,不知道什么鬼!!

     

 

© 著作权归作者所有

共有 人打赏支持
粉丝 3
博文 12
码字总数 4670
作品 0
浦东
高级程序员
私信 提问
springmvc+hibernate4 怎么实现数据层的多租户?

springmvc+hibernate4 怎么实现数据层的多租户?

owenG
2015/05/11
773
4
java,spring,hibernate,oracle

昨天自己搭了一个springmvc+hibernate4的框架,全注解。之前连接mysql的时候是没有任何问题的,但是连oracle这块就有问题了。现在用gecgetcurrentsession的时候数据保存不到数据库了,用get...

魔夜C
2016/09/01
123
0
Hibernate Validator bean-validator-3.0-JBoss-4.0.2

springMVC+hibernate4,配置框架时,用Junit测试时,会出现Hibernate Validator bean-validator-3.0-JBoss-4.0.2, Caused by: org.hibernate.HibernateException: Error applying BeanVali......

阿斯兰
2013/07/16
0
0
服务器断电导致php的session丢失

公司的服务器由于断电导致重启,原本以为不会导致什么问题,可还是莫名的出现了问题。进入网站后台,需要输入验证码,可怎么输入都提示不正确。于是就开始断点调试,最终调试的结果,验证码的...

sharephper
2013/01/05
0
0
laravel多站点session冲突的解决方案

在同一台服务器上使用nginx将多个laravel应用部署到不同端口,在使用中会出现session冲突的问题,即A应用的session被B应用同名session使用,反过来B应用对session的更改会导致A应用发生异常。...

冠岑
2016/10/05
100
1

没有更多内容

加载失败,请刷新页面

加载更多

如何在 Linux 系统查询机器最近重启时间

在你的 Linux 或类 UNIX 系统中,你是如何查询系统上次重新启动的日期和时间?怎样显示系统关机的日期和时间? last 命令不仅可以按照时间从近到远的顺序列出该会话的特定用户、终端和主机名...

来来来来来
今天
2
0
Redis协议是什么样的

前言 我们用过很多redis的客户端,有没有相过自己撸一个redis客户端? 其实很简单,基于socket,监听6379端口,解析数据就可以了。 redis协议 解析数据的过程主要依赖于redis的协议了。 我们...

春哥大魔王的博客
今天
4
0
乱入Linux界的我是如何学习的

欢迎来到建哥学Linux,咳!咳!咳!开个玩笑哈,我是一个IT男,IT界的入门选手,正在学习Linux。 在之前,一直想进军IT界,学习IT技术,但是苦于没有人指导,也不知道学什么,最开始我自己在...

linuxCool
今天
3
0
携程Apollo统一配置中心的搭建和使用(java)

一.Apollo配置中心介绍 1、What is Apollo 1.1 Apollo简介 Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到...

morpheusWB
今天
3
0
远程获得的有趣的linux命令

使用这些工具从远程了解天气、阅读资料等。 我们即将结束为期 24 天的 Linux 命令行玩具日历。希望你有一直在看,如果没有,请回到开始,从头看过来。你会发现 Linux 终端有很多游戏、消遣和...

Linux就该这么学
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部