About Me

My photo
"Enoughtheory.com" had its humble beginning in the year 2011 by ( Founder of Enoughtheory.com ) Mr Ravi Kant Soni , an Enterprise Java and Spring Framework Specialist, with a bachelor degree (B.E) in Information Science and Engineering from Reva Institute of Technology at Bangalore. He has been into the software development discipline for many years now. Ravi has worn many hats throughout his tenure, ranging from software development, designing multi-tenant applications, integration of new technology into an existing system, to his current love of writing a Spring Framework book. Currently, he is a lead engineer at HCL Technology. Ravi has focused on Web and Enterprise development using Spring Framework for most of his career and has been extensively involved in application design and implementation. He has developed applications for Core-Bank, HR and Payroll System, and e-Commerce systems using Spring Framework. Ravi Kant Soni is author of book "Learning Spring Application development" http://learningspringapplicationdevelopment.com

Tuesday 8 November 2011

Lazy Fetching


  • Lazy fetching allows the fetching of a relationship to be deferred until it is accessed.
  • "Lazy loading" means that an entity will be loaded only when you actually accesses the entity for the firsttime.
  • This saves the cost of preloading/prefilling all the entities in a large dataset beforehand while you after all actually don't need all of them.
  • Lazy setting decides whether to load child objects while loading the Parent Object.
 The actual lazy loading is then done inside the methods of the PersistentSet which Hibernate uses "under the hoods" to assign the collection of entities as Set.
E.g.
public class Parent {
    private Set<Child> children;

    public Set<Child> getChildren() {
        return children;
    }
}
.
public void doSomething() {
    Set<Child> children = parent.getChildren(); // Still contains nothing.

    // Whenever you call one of the following (indirectly), 
    // Hibernate will start to actually load and fill the set.
    children.size();
    children.iterator();
}
  • You need to do this setting respective hibernate mapping file of the parent class.Lazy = true (means not to load child)By default the lazy loading of the child objects is true. This make sure that the child objects are not loaded unless they are explicitly invoked in the application by calling getChild() method on parent. In this case hibernate issues a fresh database call to load the child when getChild() is actully called on the Parent object
  • But in some cases you do need to load the child objects when parent is loaded. Just make the lazy=false and hibernate will load the child when parent is loaded from the database.
  • Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used
ISSUES:
  • The cost of retrieving and building an object's relationships, far exceeds the cost of selecting the object. This is especially true for relationships such as manager or managedEmployees such that if any employee were selected it would trigger the loading of every employee through the relationship hierarchy. Obviously this is a bad thing, and yet having relationships in objects is very desirable.
USE:
  • In JPA lazy fetching can be set on any relationship using the fetch attribute.
  • The fetch can be set to either LAZY or EAGER as defined in the FetchType enum. 
  • The default fetch type is LAZY for all relationships except for OneToOne andManyToOne, but in general it is a good idea to make every relationship LAZY.
  • The EAGER default for OneToOne and ManyToOne is for implementation reasons (more difficult to implement), not because it is a good idea.

Example of a lazy one to one relationship annotations

@Entity
public class Employee {
  @Id
  private long id;
  ...
  @OneToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="ADDR_ID")
  private Address address;
  ...
}

Example of a lazy one to one relationship XML

<entity name="Employee" class="org.acme.Employee" access="FIELD">
    <attributes>
        <id name="id"/>
        <one-to-one name="address" fetch="LAZY">
            <join-column name="ADDR_ID"/>
        </one-to-one>
    </attributes>
</entity>

Magic

  • For OneToOne and ManyToOne relationships the magic normally involves some sort of byte code manipulation of the entity class, or creation of a subclass.
  • This allows the access to the field or get/set methods to be intercepted, and for the relationships to be first retrieved before allowing access to the value.

Serialization, and Detaching

  • A major issue with lazy relationships, is ensuring that the relationship is still available after the object has been detached, or serialized.
  • For most JPA providers, after serialization any lazy relationship that was not instantiated will be broken, and either throw an error when accessed, or return null.
  • The naive solution is to make every relationship eager.

No comments:

Post a Comment