论坛首页 Java企业应用论坛

发现ibatis最近版本的一个Bug

浏览 3711 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-12-12  
   我发现如果要使SqlMapConfig.xml里<settings/>元素的默认配置生效(如缓存和延迟加载默认都是启用的),那么<settings/>元素是不可缺少的,即使你不显式配置里面的属性。换句话说,如果没有这个元素的话,所有里面的Boolean属性值如cacheModelsEnabled,lazyLoadingEnabled 都是false,而不是文档里的那些值,所以你如果认为默认配置都可以接受而偷懒没自己在SqlMapConfig.xml里加入<settings/>的元素的话,问题就出来了,我发现2.3.4和2.3.0都有这个问题。
   
    通过查看Ibatis处理xml文件的相关源码,大致了解了里面的机制,貌似发现了原因
   
   
      String resource = "SqlMapConfig.xml";
      Reader reader = Resources.getResourceAsReader (resource);
      SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
    

    
    以上代码是载入SqlMapConfig.xml的一般方法,buildSqlMapClient方法是这样的:

   
      public static SqlMapClient buildSqlMapClient(Reader reader) {
    //    return new XmlSqlMapClientBuilder().buildSqlMap(reader);
         return new SqlMapConfigParser().parse(reader);
     }
   

   
    SqlMapConfigParser类的构造函数如下代码,
   
       
      	public SqlMapConfigParser() {
		parser.setValidation(true);
		parser.setEntityResolver(new SqlMapClasspathEntityResolver());

		addSqlMapConfigNodelets();
		addGlobalPropNodelets();
		addSettingsNodelets();
		addTypeAliasNodelets();
		addTypeHandlerNodelets();
		addTransactionManagerNodelets();
		addSqlMapNodelets();
		addResultObjectFactoryNodelets();

	}
   

  
   add...()这些方法都是将配置文件中各个节点的Xpath及处理这些节点的事件加入到一个HashMap中,这里简单补充下ibatis解析Xml文件的机制:ibatis用一个自定义的NedeletParser类来解析Xml,此类类似于Sax API,但不同的是Sax是一个单独的Callback对应所有的节点,而NodeletParser 是通过一系列的Callback对应不同的节点,也就是用Hashmap事先注册节点的XPath和解析它们的事件,以备今后调用。然后在载入用户的SqlMapConfig.xml时,用递归的方法找出里面所有节点(从父节点到所有子节点)的xpath值,然后通过该值(Key)从Hash表获取它们的事件处理方法进行解析。
  
   所以如果没有加入<settings/>元素的话,NodeletParser就找不到该节点的Xpath,因而就没有调用处理该节点
的事件,cacheModelsEnabled这些属性值(大都在SqlMapExecutorDelegate里,该类是运行Sql的核心引擎,具体见源码)默认都没有进行初始化,所以都为false,而文档里所说的cacheModelsEnabled等属性默认都为True其实是addSettingsNodelets方法里处理的,以下为代码片段
  
     private void addSettingsNodelets() {
		parser.addNodelet("/sqlMapConfig/settings", new Nodelet() {
			public void process(Node node) throws Exception {
                     Properties attributes = NodeletUtils.parseAttributes(node,state.getGlobalProps());
		   SqlMapConfiguration config = state.getConfig();
                      ......
		   String cacheModelsEnabledAttr = attributes.getProperty("cacheModelsEnabled");
		   boolean cacheModelsEnabled = (cacheModelsEnabledAttr == null || "true".equals(cacheModelsEnabledAttr));
	            config.setCacheModelsEnabled(cacheModelsEnabled);
                     ......//简洁起见,省略其他代码,
}
  


   从以上代码可看出如果<settings/>元素里没有cacheModelsEnabled 等属性时(也就是cacheModelsEnabledAttr为Null),将会被设置为True。

   但问题是如果没有<settings/>元素,这段代码就不会执行。。
   发表时间:2008-12-12  
给ibatis开发团队上报了这个问题,貌似确实是个Bug,官网上已经把ibatis-2.3.4去掉了,现在是2.3.3,不知道是不是也有这个问题,估计最近会有版本更新了
0 请登录后投票
   发表时间:2008-12-13  
有2.3.4.276 和以前一样的
0 请登录后投票
   发表时间:2008-12-13   最后修改:2008-12-13
刚看了是2.3.4,但昨天确实是挂着2.3.3,呵呵,Jeff Butler也认为这是一个Bug,

http://www.nabble.com/Is-this-a-bug---td20954288.html
0 请登录后投票
   发表时间:2008-12-21  
所以 我平时的习惯是, 不管任何东西是不是默认的, 我都回加上,大部分东西我是这么搞的, 天知道什么时候DEFAULT值把我搞死。 哈哈
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics