ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael He <hyxw5...@yahoo.com.cn>
Subject Is this a bug ?
Date Thu, 11 Dec 2008 12:14:51 GMT

Hi all
       
      I currently use ibatis-2.3.4 and find that the <settings> element in
SqlMapConfig.xml shouldn't missed if you want the default  settings in this
tag to take effect even if you don't put any attributes in it.In other
words,if you don't leave the <settings> element in SqlMapConfig.xml,all the
boolean attributes(like cacheModelsEnabled,lazyLoadingEnabled) will be false
instead of the default value as said by the
docs(cacheModelsEnabled,lazyLoadingEnabled are both setted as true defaultly
according to the docs) .

      I digged into the source code,trying to find the reason and may be i
have located the problem :)

 ibatis uses the SqlMapConfigParser class to load the SqlMapConfig file ,for
example ,the code below parse the SqlMapConfig file as a reader:

    public static SqlMapClient buildSqlMapClient(Reader reader) {
//    return new XmlSqlMapClientBuilder().buildSqlMap(reader);
    return new SqlMapConfigParser().parse(reader);
  }
  
   ibatis actually uses a customed parser called the NodeletParser to parse
xml nodes,i paste the comments of this parser below:
/**
 * The NodeletParser is a callback based parser similar to SAX.  The big
 * difference is that rather than having a single callback for all nodes,
 * the NodeletParser has a number of callbacks mapped to
 * various nodes.   The callback is called a Nodelet and it is registered
 * with the NodeletParser against a specific XPath.
 */

 when SqlMapConfigParser is first initialized,it will store all the
Xpath(predifined xpathes for all the elements in the SqlMapConfig file) and
Nodelet as the key-value pair in a hashmap in NodeletParser class for
possible processes in the future.
  The SqlMapConfig will be parsed by calling the parse(reader) method,the
NodeletParser will use a recursive method that walkes the DOM tree,
registers XPaths and calls Nodelets registered under those XPaths.
The process method in the codes below  nodelet.process(node) actually
processes all the elments and their children.

  private void processNodelet(Node node, String pathString) {
    Nodelet nodelet = (Nodelet) letMap.get(pathString);
    if (nodelet != null) {
      try {
        nodelet.process(node);
      } catch (Exception e) {
        throw new RuntimeException("Error parsing XPath '" + pathString +
"'.  Cause: " + e, e);
      }
    }
  }

the process method for setting element is below,as you can see ,the
attribute like setLazyLoadingEnabled is setted as true if you don't specify
the value

public void process(Node node) throws Exception {
				Properties attributes = NodeletUtils.parseAttributes(node,
						state.getGlobalProps());
				SqlMapConfiguration config = state.getConfig();

				String classInfoCacheEnabledAttr = attributes
						.getProperty("classInfoCacheEnabled");
				boolean classInfoCacheEnabled = (classInfoCacheEnabledAttr == null ||
"true"
						.equals(classInfoCacheEnabledAttr));
				config.setClassInfoCacheEnabled(classInfoCacheEnabled);

				String lazyLoadingEnabledAttr = attributes
						.getProperty("lazyLoadingEnabled");
				boolean lazyLoadingEnabled = (lazyLoadingEnabledAttr == null || "true"
						.equals(lazyLoadingEnabledAttr));
				config.setLazyLoadingEnabled(lazyLoadingEnabled);

				String statementCachingEnabledAttr = attributes
						.getProperty("statementCachingEnabled");
				boolean statementCachingEnabled = (statementCachingEnabledAttr == null
|| "true"
						.equals(statementCachingEnabledAttr));
				config.setStatementCachingEnabled(statementCachingEnabled);

				String cacheModelsEnabledAttr = attributes
						.getProperty("cacheModelsEnabled");
				boolean cacheModelsEnabled = (cacheModelsEnabledAttr == null || "true"
						.equals(cacheModelsEnabledAttr));
				config.setCacheModelsEnabled(cacheModelsEnabled);

				String enhancementEnabledAttr = attributes
						.getProperty("enhancementEnabled");
				boolean enhancementEnabled = (enhancementEnabledAttr == null || "true"
						.equals(enhancementEnabledAttr));
				config.setEnhancementEnabled(enhancementEnabled);

				String useColumnLabelAttr = attributes
						.getProperty("useColumnLabel");
				boolean useColumnLabel = (useColumnLabelAttr == null || "true"
						.equals(useColumnLabelAttr));
				config.setUseColumnLabel(useColumnLabel);

				String forceMultipleResultSetSupportAttr = attributes
						.getProperty("forceMultipleResultSetSupport");
				boolean forceMultipleResultSetSupport = "true"
						.equals(forceMultipleResultSetSupportAttr);
				config
						.setForceMultipleResultSetSupport(forceMultipleResultSetSupport);

				String defaultTimeoutAttr = attributes
						.getProperty("defaultStatementTimeout");
				Integer defaultTimeout = defaultTimeoutAttr == null ? null
						: Integer.valueOf(defaultTimeoutAttr);
				config.setDefaultStatementTimeout(defaultTimeout);

				String useStatementNamespacesAttr = attributes
						.getProperty("useStatementNamespaces");
				boolean useStatementNamespaces = "true"
						.equals(useStatementNamespacesAttr);
				state.setUseStatementNamespaces(useStatementNamespaces);
			}     
so if there's no setting element in the config file,it will not be found in
the hashMap,so the nodelet will be null and the process(node) method will
not be called,thus all the setting attributes will be the default boolean
value false.That's where the problem is.

I'm a newbie so may be i have missed something or have made something
wrong,if I have, please let me know ,any help and comment will be
appreciated.

-- 
View this message in context: http://www.nabble.com/Is-this-a-bug---tp20954288p20954288.html
Sent from the iBATIS - User - Java mailing list archive at Nabble.com.


Mime
View raw message