ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kai Grabfelder <nos...@kinokai.de>
Subject Re: Laziness, downcasting and <discriminator,id> associations
Date Mon, 01 Dec 2008 16:34:26 GMT

I have to admit that I never used the lazy features of iBATIS. Lazyness by Default was one
of the reasons why
I moved over from hibernate to iBATIS. And I know a bunch of other devs that are not and will
not use lazy
loading. Imho it does not make sense for web applications or restful service interfaces and
introduces a lot
of problems (open session in view, serialization of result sets, performance etc.).

I'm not sure what the plans are for iBATIS 3.0. I've seen quite different opinions regarding
lazyness on the
whiteboard (http://opensource.atlassian.com/confluence/oss/display/IBATIS/iBATIS+3.0+Whiteboard)
but I don't
know the status. @Clinton: any news about that?

Nevertheless: feel free to create a jira issue with your proposed patches. And it would be
great if you could
link to all the other lazy issues that are related. Maybe we should start a vote about the
direction of lazy
loading with iBATIS in the future...



--- Original Nachricht ---
Absender: Carlos Pita
Datum: 01.12.2008 16:51
> Hi,
> I'm evaluating the possibility to migrate a web application that is already
> in production from hibernate to ibatis. As a part of this I'm implementing
> skeletal versions of our most complex mappings, as a proof of concept. The
> application contains some overlapping hierarchies rooted at interfaces that
> are certainly hard to map into hibernate entities. For example, many
> different things can be commentable, rateable, abusable (meaning that abuses
> can be reported on them), etc. These concepts are naturally modelled as
> interfaces. Bidirectional associations exist between, say, commentables and
> comments:
> commentable <-----------*> comment
> Following the example, a product and a user profile are commentables:
>     commentable <---------*> comment
>          ^   ^
>         |   |
>     product  profile
> Of course, both product and profile belong to different class hierarchies
> besides being commentable. The link from comment to commentable could be
> implemented as pointing to an union select of product and profile, or using
> a target table discriminator column as in:
> comment {
>   text
>    commentable_kind : { product, profile }
>   commentable_id
> }
> I've found at least two ways to satisfactorily map the above using ibatis,
> which encourages me to continue my evaluation and eventually get into the
> (considerable) work of migrating the entire app to ibatis.
> But then I've to say that I bumped my head against issue #1 here
> http://opensource.atlassian.com/confluence/oss/display/IBATIS/Lazy+loading+issues
> That happened when I expected to get the commentable product out of a
> comment: (Product)(comment.getCommentable()).
> Nevertheless, I found out the following patch
> https://issues.apache.org/jira/browse/IBATIS-463
> which is fine but only a kludge for the very specific situation. Why not
> allow laziness to be specified on a per subselect basis (of course, taking
> into account the default app-wide setting also)? Required changes to the
> source are minimal (the ResultMapping could be passed to loadResult in order
> it to check for the lazy attribute), and that solves the lazy downcast
> problem but also provides a finer control over laziness/eagerness of the
> association. The logic to enable laziness would then be:
> global-laziness-enabled && local-laziness-enabled -> enable laziness for
> this subselect.
> That said, for associations specified by a pair <discriminator,id> as above,
> the discriminator is available *before* fetching the associated entity. One
> way of mapping the aforementioned association is:
> <resultMap id="commentMap" class="comment">
>     ....
>    <discriminator column="commentable_kind" javaType="int">
>         <subMap value="1" resultMap="productCommentableMap"/>
>        <subMap value="2" resultMap="profileCommentableMap"/>
>     </discriminator>
> </resultMap>
> <resultMap id="productCommentMap" class="comment" extends="commentMap">
>      ....
>     <result property="commentable" column="commentable_id"
> select="selectProductById" />
> </resultMap>
> <resultMap id="profileCommentMap" class="comment" extends="commentMap">
>      ....
>     <result property="commentable" column="commentable_id"
> select="selectProfileById" />
> </resultMap>
> Obviously selectProductById would be mapped by a productMap which builds a
> product and selectProfileById by a profileMap which builds a profile:
> <select id="selectProductById" resultMap="productMap" (or
> resultClass="product")>
>     ....
> </select>
> <select id="selectProfileById" resultMap="profileMap" (or
> resultClass="profile")>
>     ....
> </select>
> But despite the concrete class info is available, as far as the association
> is lazy ibatis will generate a commentable proxy, not a product or profile
> one.
> I think it would be an improvement if instead of just considering the class
> in the bean signature ibatis also took into account the class of the
> resultmap involved, and favoured the "more concrete" one, because sometimes
> the mapping containes more precise information about the specific use case
> than the general interface. In this case, product and profile would be
> picked instead of just commentable. This way, we have a lazy and
> downcasteable polymorphic association (for this kind of mapping).
> Briefly, I'm proposing two minor changes for the java version:
> 1) add a lazy attribute to the result tag that takes effect only when the
> select attribute is also given. This attribute won't activate laziness if
> it's globally disabled, but will deactivate it when it's globally enabled.
> 2) when creating a 1:1 proxy prefer the more concrete class between the one
> given in the property signature and the one given in the resultMap for the
> "delayed" query.
> I'm going to implement these changes anyway, because I need them. But I
> really would like to know what do you think about the ideas and whether
> you're also interested in patching the 2.x trunk or not.
> Before I mentioned that I found out two ways of mapping the
> <discriminator,id> association. The second one involves using a dynamic
> select instead of two submaps. This select (say
> selectCommentableFromKindAndId) chooses the target table (product or
> profile) according to the discriminator (kind) value. But I realized that
> the resultMap for a dynamic select is itself static, somehow diminishing the
> flexibility that dynamic tags introduce. Of course, the resultMap for the
> select could contain a discriminator to alleviate the problem. But I think
> that the resultMap is so closely related to the query that the possibility
> to modify the second (by means of dynamic tags) should be accompanied by the
> possibility to modify the first based on dynamic criteria. What do you
> think?
> Best regards
> -Carlos

View raw message