ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Carlos Pita" <carlosjosep...@gmail.com>
Subject Re: Laziness, downcasting and <discriminator,id> associations
Date Mon, 01 Dec 2008 17:22:58 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.).


Could you please develop your position a bit more? I'm interested in any
approach that gets rid of any amount of magic that works behind the scenes.
If avoiding all laziness happens to be a workable approach, I'll be all for
it.

For example, to trigger the discussion:

Do you work out a query per use case that eager fetches (by means of joins
and/or immediate subselects) the exact graph needed for that use case?

There are obvious problems with join fetches for entities that have more
than one 1-N relationships because of the potentially huge cartesian product
that they generate; I can figure out more or less laboriuos solutions to
them using ibatis to fetch and map one or more of the associated collections
by separate queries and then merging the results. And anyway lazy fetching
would avoid the cartesian product to incur in the even worse n+1 problem.
How do you approach this kind of situation?

Then, there are bidirectional associations, which I currently implement
keeping a memory cache with weak references to get the N-1 side
(child.getParent() should be a cache hit). Eagerness would imply an extra
query here, for a parent that more often than not has been already fetched.

That are some of the many issues that came to my mind.

> 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...

Sure.


Best regards
-Carlos


>
>
> 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?
>
>
>
>
> Regards
>
> Kai
>
>
> --- 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
> >
>
>

Mime
View raw message