Hi, I've selected iBATIS.NET for a current project and have run across a few (possible) issues which I thought I'd drop to the list. All effecting at least the 1.6.0/1.9.0 releases, I'm not 100% sure if these are all bugs or behaviour by design or even me being stupid, but I would definitely appreciate comment.
Issue 1: Possible fix for XSDs It's possible to put a subMap element in a mapping file without a discriminator element. This throws an ConfigurationException with the text "The discriminator is null, but somehow a subMap was reached. This is a bug.". Perhaps this should be enforced in the schema, maybe by making subMap a child of discriminator? Regardless, the text implies that users of the library should not see this exception and thought it worth a mention. Stack track follows: at IBatisNet.DataMapper.Configuration.ResultMapping.ResultMap.Initialize(ConfigurationScope configScope) at IBatisNet.DataMapper.Configuration.Serializers.ResultMapDeSerializer.Deserialize(XmlNode node, ConfigurationScope configScope) at IBatisNet.DataMapper.Configuration.DomSqlMapBuilder.BuildResultMap() at IBatisNet.DataMapper.Configuration.DomSqlMapBuilder.ConfigureSqlMap() at IBatisNet.DataMapper.Configuration.DomSqlMapBuilder.Initialize() at IBatisNet.DataMapper.Configuration.DomSqlMapBuilder.Build(XmlDocument document, DataSource dataSource, Boolean useConfigFileWatcher, Boolean isCallFromDao) Issue 2: Incorrect usage of groupBy attribute throws unhelpfull exception Not just is it unhelpful with regards to finding my mistake, it is also thrown when the statement is first used as opposed to during configuration. The exception occurs when the groupBy attribute is populated with the column name instead of the property/field name. Whilst obviously an exception is the desired response, and of course I should read the documentation better(!), it was a pain to troubleshoot due to the exception text and it not being thrown at configure time. Exception text is "Key cannot be null.\r\nParameter name: key", stack track follows: at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Hashtable.set_Item(Object key, Object value) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader, Object keys) at IBatisNet.DataMapper.MappedStatements.BaseStrategy.FillObjectWithReaderAndResultMap(RequestScope request, IDataReader reader, IResultMap resultMap, Object resultObject) at IBatisNet.DataMapper.MappedStatements.PropertyStrategy.ResultMapStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader, Object keys) at IBatisNet.DataMapper.MappedStatements.ResultStrategy.GroupByStrategy.Process(RequestScope request, IDataReader& reader, Object resultObject) at IBatisNet.DataMapper.MappedStatements.ResultStrategy.MapStrategy.Process(RequestScope request, IDataReader& reader, Object resultObject) at IBatisNet.DataMapper.MappedStatements.MappedStatement.RunQueryForObject[T](RequestScope request, ISqlMapSession session, Object parameterObject, T resultObject) at IBatisNet.DataMapper.MappedStatements.MappedStatement.ExecuteQueryForObject[T](ISqlMapSession session, Object parameterObject, T resultObject) at IBatisNet.DataMapper.MappedStatements.MappedStatement.ExecuteQueryForObject[T](ISqlMapSession session, Object parameterObject) at IBatisNet.DataMapper.SqlMapper.QueryForObject[T](String statementName, Object parameterObject) Issue 3: N+1 select lists solution throws an exception when the list is empty As above, when there are no elements in the child list, an NullReferenceException is thrown when the statement is first used. Now this is a real kick in the teeth, I was getting all excited by how cool it was to populate my huge object graph with such little work and a single select untill all of a sudden I run into this when a list is null! Now although in my particular case it's not absolutely critical to have this working, I'd rather keep the flexibility than hard code this limitation into my validation routines. Exception text is "Object reference not set to an instance of an object.", and the stack trace follows: at IBatisNet.DataMapper.Configuration.ResultMapping.ResultMap.ResolveSubMap(IDataReader dataReader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader, Object keys) at IBatisNet.DataMapper.MappedStatements.BaseStrategy.FillObjectWithReaderAndResultMap(RequestScope request, IDataReader reader, IResultMap resultMap, Object resultObject) at IBatisNet.DataMapper.MappedStatements.PropertyStrategy.ResultMapStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader, Object keys) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Get(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader) at IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Set(RequestScope request, IResultMap resultMap, ResultProperty mapping, Object& target, IDataReader reader, Object keys) at IBatisNet.DataMapper.MappedStatements.ResultStrategy.GroupByStrategy.Process(RequestScope request, IDataReader& reader, Object resultObject) at IBatisNet.DataMapper.MappedStatements.ResultStrategy.MapStrategy.Process(RequestScope request, IDataReader& reader, Object resultObject) at IBatisNet.DataMapper.MappedStatements.MappedStatement.RunQueryForObject[T](RequestScope request, ISqlMapSession session, Object parameterObject, T resultObject) at IBatisNet.DataMapper.MappedStatements.MappedStatement.ExecuteQueryForObject[T](ISqlMapSession session, Object parameterObject, T resultObject) at IBatisNet.DataMapper.MappedStatements.MappedStatement.ExecuteQueryForObject[T](ISqlMapSession session, Object parameterObject) at IBatisNet.DataMapper.SqlMapper.QueryForObject[T](String statementName, Object parameterObject) Hope some of this will be helpful to the development effort. Regards, Sean

