title: Lazy Loading using MyBatis 3 with Java
body: <p>I am using Mybatis (3.2.7 version) as an ORM framework for my JAVA project.
  As I'm from JPA background, I was keen to explore the LAZYLOADING supported by Mybatis.
  But I couldn't get across anything substantial.
  <br/><b>(I am configuring MYBATIS using JAVA API and annotations solely for querying purpose)</b></p>
  
  <p>As per the Mybatis documentation: 
  <i>
  <b>1. lazyLoadingEnabled: default value=TRUE</b></p>
  
  <p>Globally enables or disables lazy loading. When enabled, all relations will be lazily 
  loaded. This value can be superseded for an specific relation by using the <b>fetchType </b>attribute 
  on it.</p> 
  
  <p><b>2. aggressiveLazyLoading : default value=TRUE</b></p>
  
  <p>When enabled, an object with lazy loaded properties will be loaded entirely upon a call to any of the lazy properties. Otherwise, each property is loaded on demand. </p> 
  
  <p></i></p>
  
  <p>Using the following attributes, I tried the following code:</p>
  
  <p>a. JAVA Classes :</p>
  
  <p>Feedback.java</p>
  
  <pre><code>public class Feedback implements Serializable {
  private static final long serialVersionUID = 1L;
  
  private int id;
  private String message;
  
     /**
     * while loading Feedback, I want sender object to be lazily loaded
     */
  private User sender;
  private boolean seen;
  
  // getters and setters
  }
  </code></pre>
  
  <p>User.java</p>
  
  <pre><code>public class User implements Serializable, {
  private static final long serialVersionUID = 1L;
  private int id;
  private String email;
  
  // getters and setters
  }
  </code></pre>
  
  <p>b. DB schema:</p>
  
  <p>Feedback table</p>
  
  <pre><code>                Table "public.feedback"
  
    Column | Type      |    Modifiers                       
  -------------+-----------+-------------------------------------------------------
   id          | integer   | PRIMARY KEY
   seen        | boolean   | not null
   sender_id   | integer   | FOREIGN KEY (sender_id) REFERENCES users(id)
   message     | text      | 
  </code></pre>
  
  <p>User Table:</p>
  
  <pre><code>                Table "public.users"
  
  Column   | Type     |     Modifiers                      
  -------------+----------+----------------------------------------------------
  id          | integer  | PRIMARY KEY
  email       | text     | 
  </code></pre>
  
  <p>c. Configuring MyBatis via JAVA API:</p>
  
  <pre><code>DataSource dataSource = new PGSimpleDataSource();
          ((PGSimpleDataSource) dataSource).setServerName("localhost");
          ((PGSimpleDataSource) dataSource).setDatabaseName(dbName);
          ((PGSimpleDataSource) dataSource).setPortNumber(5432);
          ((PGSimpleDataSource) dataSource).setUser(new UnixSystem().getUsername());
          ((PGSimpleDataSource) dataSource).setPassword("");
  
          TransactionFactory transactionFactory = new JdbcTransactionFactory();
          Environment environment = new Environment(dbName, transactionFactory, dataSource);
          Configuration configuration = new Configuration(environment);
               configuration.addMapper(FeedbackMapper.class);
  
              //
               configuration.setAggressiveLazyLoading(false);
               sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
  </code></pre>
  
  <p>d. Querying DB and DB Queries in Feedbackmapper:</p>
  
  <p>d.1 Code in Feedbackmapper:</p>
  
  <pre><code>@Select("SELECT f.id, f.message, f.seen, f.sender_id FROM feedback f WHERE f.id= #{feedbackId}")
  @Results(value = { 
          @Result(property = "id", column = "id"),
          @Result(property = "sender", column = "sender_id", javaType = User.class, one = @One(select = "getUser", fetchType=FetchType.DEFAULT))
  })
  public Feedback getFeedback(@Param("feedbackId") int feedbackId);
  
  @Select("SELECT id, email FROM users WHERE id=#{id}")
  public User getUser(int id);
  </code></pre>
  
  <p>d.2: Code to invoke the queries in feedbackMapper</p>
  
  <pre><code>    // setup Mybatis session factory and config
      Feedback feedback =feedbackMapper.getFeedback(70000);
      System.out.println(feedback);
  </code></pre>
  
  <p><b>But still the "sender"  object is populated upon querying the getFeedback(id). I expect the sender object shouldn't be populated immediately but only when I call getSender() on the fetched feedback object . Please help</b>.</p>
  
  <p>My recent Observations:</p>
  
  <p>Mybatis team has indeed got it wrong in their documentation ie in documentation:</p>
  
  <ol>
  <li><p>lazyLoadingEnabled: default value=TRUE</p></li>
  <li><p>aggressiveLazyLoading : default value=TRUE</p>
  
  <p>But looking at their source code: </p>
  
  <pre><code> protected boolean lazyLoadingEnabled = false;
   protected boolean aggressiveLazyLoading = true;
  </code></pre>
  
  <p>**However that being corrected, the results are not affected and lazy loading isnt working :( **</p></li>
  </ol>