groupBy incorrectly handles left outer join results where right part is empty
-----------------------------------------------------------------------------
Key: IBATISNET-206
URL: https://issues.apache.org/jira/browse/IBATISNET-206
Project: iBatis for .NET
Issue Type: Bug
Components: DataMapper
Affects Versions: DataMapper 1.6
Reporter: Ihar Bury
We use the newly added groupBy functionality as follows:
<resultMap id="ConsumptionHistoryUsers" class="User"
groupBy="Id">
<result property="Id" column="id" />
...
<result property="filteredTopContentConsumptionHistory"
resultMapping="UserMap.ConsumptionHistoryUsersContent" />
</resultMap>
<resultMap id="ConsumptionHistoryUsersContent" class="Content">
<result property="Id" column="content_id" />
<result property="Creator"
resultMapping="UserMap.ConsumptionHistoryUsersContentCreator" />
<result property="DateCreated"
column="content_date_created" />
<result property="Title" column="content_title" />
<discriminator type="int" column="content_subtype_id" />
<subMap value="5"
resultMapping="ConsumptionHistoryUsersBlog" />
</resultMap>
<resultMap id="ConsumptionHistoryUsersBlog" class="BlogContent"
extends="UserMap.ConsumptionHistoryUsersContent">
</resultMap>
The result map is for select SQL like
select *
from User
left outer join Content on ...
This works well in the cases where each selected User has at least one Content
joined to it. But when there is one User that doesn't have any corresponding
content, a failure occurs. The record returned from the database has values for
User and has null values for all Content columns. iBATIS should just store an
empty collection to the resulting User object in this case but it tries to load
all those nulls as a Content object. In our case that ends up with
NullReferenceException while analizing the discriminator value.
subMap = _discriminator.GetSubMap(
dataBaseValue.ToString() );
where dataBaseValue == null
>
> IBatisNet.DataMapper.dll!IBatisNet.DataMapper.Configuration.ResultMapping.ResultMap.ResolveSubMap(System.Data.IDataReader
> dataReader = {IBatisNet.DataMapper.Commands.DataReaderDecorator}) Line 444
> C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Get(IBatisNet.DataMapper.Scope.RequestScope
request = {IBatisNet.DataMapper.Scope.RequestScope},
IBatisNet.DataMapper.Configuration.ResultMapping.IResultMap resultMap =
{IBatisNet.DataMapper.Configuration.ResultMapping.ResultMap},
IBatisNet.DataMapper.Configuration.ResultMapping.ResultProperty mapping =
{IBatisNet.DataMapper.Configuration.ResultMapping.ResultProperty}, ref object
target = {Tw.Core.BusinessLayer.ObjectModel.Users.User},
System.Data.IDataReader reader =
{IBatisNet.DataMapper.Commands.DataReaderDecorator}) Line 99 + 0x19 bytes
C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.MappedStatements.PropertStrategy.GroupByStrategy.Set(IBatisNet.DataMapper.Scope.RequestScope
request = {IBatisNet.DataMapper.Scope.RequestScope},
IBatisNet.DataMapper.Configuration.ResultMapping.IResultMap resultMap =
{IBatisNet.DataMapper.Configuration.ResultMapping.ResultMap},
IBatisNet.DataMapper.Configuration.ResultMapping.ResultProperty mapping =
{IBatisNet.DataMapper.Configuration.ResultMapping.ResultProperty}, ref object
target = {Tw.Core.BusinessLayer.ObjectModel.Users.User},
System.Data.IDataReader reader =
{IBatisNet.DataMapper.Commands.DataReaderDecorator}, object keys = null) Line
71 + 0x15 bytes C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.MappedStatements.ResultStrategy.GroupByStrategy.Process(IBatisNet.DataMapper.Scope.RequestScope
request = {IBatisNet.DataMapper.Scope.RequestScope}, ref
System.Data.IDataReader reader =
{IBatisNet.DataMapper.Commands.DataReaderDecorator}, object resultObject =
null) Line 88 + 0x2e bytes C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.MappedStatements.ResultStrategy.MapStrategy.Process(IBatisNet.DataMapper.Scope.RequestScope
request = {IBatisNet.DataMapper.Scope.RequestScope}, ref
System.Data.IDataReader reader =
{IBatisNet.DataMapper.Commands.DataReaderDecorator}, object resultObject =
null) Line 64 + 0x14 bytes C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.MappedStatements.MappedStatement.RunQueryForList<Tw.Core.BusinessLayer.ObjectModel.Users.User>(IBatisNet.DataMapper.Scope.RequestScope
request = {IBatisNet.DataMapper.Scope.RequestScope},
IBatisNet.DataMapper.ISqlMapSession session =
{IBatisNet.DataMapper.SqlMapSession}, object parameterObject =
{Tw.Core.DataLayer.Mappers.Users.UserMapper.UserConsumptionHistoryUsersParams},
System.Collections.Generic.IList<Tw.Core.BusinessLayer.ObjectModel.Users.User>
resultObject = null,
IBatisNet.DataMapper.RowDelegate<Tw.Core.BusinessLayer.ObjectModel.Users.User>
rowDelegate = null) Line 768 + 0x17 bytes C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.MappedStatements.MappedStatement.ExecuteQueryForList<Tw.Core.BusinessLayer.ObjectModel.Users.User>(IBatisNet.DataMapper.ISqlMapSession
session = {IBatisNet.DataMapper.SqlMapSession}, object parameterObject =
{Tw.Core.DataLayer.Mappers.Users.UserMapper.UserConsumptionHistoryUsersParams})
Line 643 + 0x45 bytes C#
IBatisNet.DataMapper.dll!IBatisNet.DataMapper.SqlMapper.QueryForList<Tw.Core.BusinessLayer.ObjectModel.Users.User>(string
statementName = "GetUserConsumptionHistoryUsers", object parameterObject =
{Tw.Core.DataLayer.Mappers.Users.UserMapper.UserConsumptionHistoryUsersParams})
Line 1019 + 0x40 bytes C#
In a case without discriminator and subclasses, iBATIS attempts to create an
object with all values set to NULL, that is also incorrect.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.