[ 
https://issues.apache.org/jira/browse/IBATISNET-285?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Gilles Bayon closed IBATISNET-285.
----------------------------------

       Resolution: Fixed
    Fix Version/s: DataMapper 1.6.2
         Assignee: Gilles Bayon

in svn

> flushInterval ist calculated wrong
> ----------------------------------
>
>                 Key: IBATISNET-285
>                 URL: https://issues.apache.org/jira/browse/IBATISNET-285
>             Project: iBatis for .NET
>          Issue Type: Bug
>          Components: DataMapper
>    Affects Versions: DataMapper 1.6.1
>            Reporter: Stefan Hoehn
>            Assignee: Gilles Bayon
>             Fix For: DataMapper 1.6.2
>
>
> We noticed that if the flushInterval like in 
>       <cacheModels>
>               <cacheModel id="NavigationCache" implementation="MEMORY" 
> readOnly="false" serialize="true">
>                       <!-- User bekommen Kopien aus dem Cache -->
>                       <flushInterval minutes="1"/>
>                       <property name="Type" value="STRONG"/>
>               </cacheModel>           
>       </cacheModels>
> is provided it results in a completely wrong number. There are two bugs that 
> lead to a wrong result. The first one is very minor because it decreases the 
> given interval time by about ten milliseconds. The second one is more severe: 
> It results in a somewhat twice the time of the cache interval given in the 
> configuration.
> Bug #1: The negative default value is being added
> in FlushInterval.cs you find the following code:
>                 private long _interval = CacheModel.NO_FLUSH_INTERVAL;   // 
> equals  -99999
>                 //................
>               public void Initialize()
>               {
>                       if (_milliseconds != 0) 
>                       {
>                               _interval += (_milliseconds * 
> TimeSpan.TicksPerMillisecond) ;
>                       }
>                       if (_seconds != 0) 
>                       {
>                               _interval += (_seconds * 
> TimeSpan.TicksPerSecond) ;
>                       }
>                       if (_minutes != 0) 
>                       {
>                               _interval += (_minutes * 
> TimeSpan.TicksPerMinute) ;
>                       }
>                       if (_hours != 0) 
>                       {
>                               _interval += (_hours * TimeSpan.TicksPerHour) ;
>                       }
>                       if (_interval == 0)
>                       {
>                               _interval = CacheModel.NO_FLUSH_INTERVAL;
>                       }         
>            }
>            The result in our case is -99999+600000000 = 599900001.
>            Granted that the effect is only about 10 Milliseconds but still, 
> it is wrong :-)
> Bug #2: FlushInterval.initialize() is called twice during initialization
> If you follow the Deserialization of the DomSqlMapBuilder in 
> ConfigureSQLMap()  you will find the following code,which calls 
> CacheModelDeSerializer.Deserialize():
> #region Load CacheModels
>                       if (_configScope.IsCacheModelsEnabled)
>                       {
>                               CacheModel cacheModel;
>                               foreach (XmlNode xmlNode in 
> _configScope.SqlMapDocument.SelectNodes( 
> ApplyMappingNamespacePrefix(XML_CACHE_MODEL), 
> _configScope.XmlNamespaceManager))
>                               {
>                                       cacheModel = 
> CacheModelDeSerializer.Deserialize(xmlNode, _configScope);
>                     cacheModel.Id = 
> _configScope.ApplyNamespace(cacheModel.Id);
>                                       // Attach ExecuteEventHandler
>                                       foreach(XmlNode flushOn in 
> xmlNode.SelectNodes( ApplyMappingNamespacePrefix(XML_FLUSH_ON_EXECUTE), 
> _configScope.XmlNamespaceManager  ))
>                                       {
>                                               string statementName = 
> flushOn.Attributes["statement"].Value;
>                                               if 
> (_configScope.UseStatementNamespaces)
>                                               {
>                             statementName = 
> _configScope.ApplyNamespace(statementName); 
>                                               }
>                                               // delay registering statements 
> to cache model until all sqlMap files have been processed
>                                               IList statementNames = 
> (IList)_configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id];
>                                               if (statementNames == null)
>                                               {
>                                                       statementNames = new 
> ArrayList();
>                                               }
>                                               
> statementNames.Add(statementName);
>                                               
> _configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id] = 
> statementNames;
>                                       }
>                                       // Get Properties
>                                       foreach(XmlNode propertie in 
> xmlNode.SelectNodes( ApplyMappingNamespacePrefix(XML_PROPERTY), 
> _configScope.XmlNamespaceManager))
>                                       {
>                                               string name = 
> propertie.Attributes["name"].Value;
>                                               string value = 
> propertie.Attributes["value"].Value;
>                                       
>                                               cacheModel.AddProperty(name, 
> value);
>                                       }
>                                       cacheModel.Initialize();
>                                       _configScope.SqlMapper.AddCache( 
> cacheModel );
>                               }
>                       }
> The issue is that CacheModelDeSerializer.Deserialize(xmlNode, _configScope);  
> has the following implementation
> int count = node.ChildNodes.Count;
>                       for(int i=0;i<count;i++)
>                       {
>                               if 
> (node.ChildNodes[i].LocalName=="flushInterval")
>                               {
>                                       FlushInterval flush = new 
> FlushInterval();
>                                       NameValueCollection props = 
> NodeUtils.ParseAttributes(node.ChildNodes[i], configScope.Properties);
>                                       flush.Hours = 
> NodeUtils.GetIntAttribute(props, "hours", 0);
>                                       flush.Milliseconds = 
> NodeUtils.GetIntAttribute(props, "milliseconds", 0);
>                                       flush.Minutes = 
> NodeUtils.GetIntAttribute(props, "minutes", 0);
>                                       flush.Seconds = 
> NodeUtils.GetIntAttribute(props, "seconds", 0);
>                                       flush.Initialize();
>                                       
>                                       model.FlushInterval = flush;
>                               }
>                       }
> and therefore calls flush.Initialize() as soon as it find an property 
> "flushInterval". So far so good as this results in getting the above number: 
> 599900001
> However, back again in ConfigureSQLMap  further down it calls 
> cacheModel.Initialize(); which in turn calls _flushInterval.Initialize(); 
> again adding another 600000000 resulting in 1199900001, almost twice of what 
> we wanted. 
> The initialization-Method must no be called twice.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to