Hi,

The major problem that was present in iBATIS 2 was that lazy loaded class where 
not always of the right type.
For exemple, if I have multiple subclasses of a class.
Person
Employee inherits Person
Director inherits Employee

If I have an object Employee with a method getBoss() that returns an Employee 
(lazy loaded), I expect that sometimes it will be a director.
In iBATIS 2, testing (employee.getBoss() instanceof Director) will always be 
false. This problem is due to the fact that iBATIS does not know the real class 
of the boss property and creates a Proxy of Employee.
In iBATIS 3, testing (employee.getBoss() instanceof Director) will be true if 
the employee's boss is a Director. To know the real type, the statement must be 
executed.

Christian


-----Original Message-----
From: Carlos Pita [mailto:carlosjosep...@gmail.com] 
Sent: Wednesday, December 16, 2009 11:45 AM
To: user-java@ibatis.apache.org
Subject: Lazy loading differences between ibatis 2 and 3

Hi all,

I've the following sqlmap for ibatis 2. Suppose ibatis has its lazy-loading 
feature enabled and I obtain a user U by means of findUserById. Then I call 
U.getEmail() and findMemberById is not executed. That's fine, one wouldn't 
expect the associated member to be loaded until there is a real need for it. Of 
course, if then I call
U.getMember().getDescription() findMemberById does execute its select, in due 
time. That said, for ibatis 3 the same example executes findMemberById as soon 
as U.getEmail() is invoked, loading the member before time. That's not 
surprising if one inspects the code of ResultObjectProxy (relevant parts copied 
below). Is this intended to work the way it does or is it a bug?

<sqlMap namespace="User">

        <resultMap id="userMap" class="User">
        <result property="email" column="email"/>
        <result property="member" column="member_id" select="findMemberById"/>
        </resultMap>

        <resultMap id="memberMap" class="Member">
        <result property="description" column="description"/>
        </resultMap>

        <select id="findUserById" resultMap="userMap">
                select * from qpoint_user where id = #id#
        </select>

        <select id="findMemberById" resultMap="memberMap">
                select * from cpp_member where member_id = #id#
        </select>

</sqlMap>


public class ResultObjectProxy {

   public Object invoke(Object o, Method method, Object[] args) throws 
Throwable {
      try {
        if (!Object.class.equals(method.getDeclaringClass()) &&
PropertyNamer.isGetter(method.getName())) {
            lazyLoader.loadAll(); <-- this loads all asociations for every 
getter invoked on this proxy
        }
        return method.invoke(target, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
}

Regards
--
Bardamu

---------------------------------------------------------------------
To unsubscribe, e-mail: user-java-unsubscr...@ibatis.apache.org
For additional commands, e-mail: user-java-h...@ibatis.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: user-java-unsubscr...@ibatis.apache.org
For additional commands, e-mail: user-java-h...@ibatis.apache.org

Reply via email to