The problem may be that for this to work you need to have
useStatementNamespaces set to true in your config file?
Sean
On 7/23/07, Kamiel Wanrooij <[EMAIL PROTECTED]> wrote:
Hi,
We are using iBatis.NET in combination with a fairly large domain model,
with lots of inheritance in the domain objects. The discriminator tag works
great most of the time, but recently I've run into some issues that I cannot
seem to solve.
I will post some snippets to make my point clear. They are a
simplification of the real deal, since we have several levels of
inheritance, and the result maps inherit as well.
Say, we have an AbstractParent with ConcreteChildOne and ConcreteChildTwo
subclasses. We store these in three database tables, where shared fields are
in the parent table, and specific information in the child tables
referencing their primary key to the parent table. We also store a type in
the parent table to keep track of which entry is which concrete type:
parent:
id type
1 1
2 1
3 2
4 1
childone:
parent_id fieldone
1 'One'
2 'Two'
4 'Four'
childtwo:
parent_id fieldtwo
3 'Three is quite different'
We inner join them to retrieve the complete set of data.
We use an sqlMap like this to retrieve the objects:
<sqlMap namespace="Parent"
xmlns="http://ibatis.apache.org/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<resultMaps>
<!-- Class is a hashmap since we cannot use an abstract class as a
result type. -->
<resultMap id="IdentityResult" class="hashmap">
<discriminator column="parenttype_id" />
<subMap value="1" resultMapping="
ConcreteChildOne.IdentityResult"/>
<subMap value="2" resultMapping="
ConcreteChildTwo.IdentityResult"/>
</resultMap>
</resultMaps>
<statements>
<statement id=" Parent.FindById" resultMap=" Parent.IdentityResult"
parameterClass="int">
-- First fetch the type, then execute the corresponding
statement
DECLARE @type_id smallint
SELECT @type_id = [parenttype_id] FROM [parent] WHERE
[id]=#value#
IF @type_id = 1
<include refid="ConcreteChildOne.FindById" /> <!-- inner join
of childone and parent -->
ELSE IF @type_id = 2
<include refid="ConcreteChildTwo.FindById" /> <!-- inner join
of childtwo and parent -->
</statement>
</statements>
<sqlMap>
The ConcreteChildOne.IdentityResult and ConcreteChildTwo.IdentityResultare
declared in their own files and namespaces, since most of the time we
access the concrete types directly. The two SQL snippets referenced are also
declared in those files. These are declared before the parent sqlMap in the
config file.
As long as the resultMaps are declared in the sqlMap above, we don't have
any problems. When I declare them in their own namespaces, they cannot load
(it tries to find them in the sqlMap above). According to the manual and
documentation, resultMapping can reference other namespaces as long as they
are declared before the referencing resultMap. We really need them to be in
separate namespaces, since this makes the resulting structure much cleaner
and maintainable.
Am I doing something wrong, or can't subMaps reference resultMaps in other
namespaces? Regular extension and resultMapping work great, also across
files and namespaces.
Thanks for any insights on the issue, and my apologies for the
not-so-short explanation of the situation.
Regards,
Kamiel