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

Sunday 13 November 2011

SiteMesh


SiteMesh3 Overview

  • SiteMesh is a web-page layout and decoration framework
  • SiteMesh intercepts requests to any static or dynamically generated HTML page requested through the web-server, processes the content and then merges it with one or more decorators to build the final result.
  • Sitemesh removes your burden of including layout related files in each and every page of your application.
Lets take a look at what sitemesh does

  • Normally websites have a common layout for all the pages. There is a header, navigation on top or left or right and a footer. Generally in such a site, we use jsp:include on every page to include the header, navigation and footer. This creates maintenance problems.
  • By using Sitemesh, we don’t need to include the header, navigation and footer into each and every page. We create only the content of the page, Sitemesh adds the header, navigation etc to the page.

Work flow:

SiteMesh in web applications

  • In a web application, SiteMesh acts as a Servler Filter.
  • It allows requests to be handled by the Servlet engine as normal, but the resulting HTML (referred to as the content) will be intercepted before being returned to the browser.
  • The intercepted content has certain properties extracted (typically the contents of the <title><head> and <body> tags and is then passed on to a second request that should return the common look and feel for the site (referred to as the decorator).
  • The decorator contains placeholders for where the properties extracted from the content should be inserted.
  • a key component of the SiteMesh architecture is the content processor. This is an efficient engine for transforming and extracting content from HTML content.
  • As with most sites, there is a header, a navigation at the top, a navigation on the left, the content goes on the right and there is a footer at the bottom.
  • If we use sitemesh, we’ll create a template page which will have the layout related to the site. That template will be applied to every page of the site.
Create a page that will contain the header, navigations and footer etc
  • SiteMesh uses a filter to intercept every request that is received by the application which we might want Sitemesh to process.
  • Sitemesh uses a configuration document (decorators.xml) to see which layout or template (called decorator) to apply to the request (if required). 

Tuesday 8 November 2011

Collection mappings - Collections


  • Collection mappings include OneToManyManyToMany,
  • JPA requires that the type of the collection field or get/set methods be one of the Java collection interfaces, CollectionListSet, or Map.

Collection Implementations

  • Your field should not be of a collection implementation type, such as ArrayList.

Duplicates

  • List in Java supports duplicate entries, and a Set does not.
  • In the database, duplicates are generally not supported.
  •  Technically it could be possible if a JoinTable is used, but JPA does not require duplicates to be supported, and most providers do not.
  • If you require duplicate support, you may need to create an object that represents and maps to the join table. This object would still require a unique Id, such as a GeneratedValue

Ordering

  • JPA allows the collection values to be ordered by the database when retrieved.
  • This is done through the @OrderBy annotation or <order-by> XML element.
  • The value of the OrderBy is a JPQL ORDER BY string. 
  • Attribute name followed by ASC or DESC for ascending or descending ordering. 
  • If no OrderByvalue is given it is assumed to be the Id of the target object.
  • The OrderBy value must be a mapped attribute of the target object.
  • Using an OrderBy does not ensure the collection is ordered in memory.You are responsible for adding to the collection in the correct order. 
  • Java does define a SortedSet interface and TreeSet collection implementation that does maintain an order.
  • You can also use the Collections.sort() method to sort a List when required. 

Example of a collection order by annotation

@Entity
public class Employee {
  @Id
  private long id;
  ...
  @OneToMany
  @OrderBy("areaCode")
  private List<Phone> phones;
  ...
}


The OrderColumn is maintained by the mapping and should not be an attribute of the target object. The table for the OrderColumn depends on the mapping. For a OneToMany mapping it will be in the target object's table. For aManyToMany mapping or a OneToMany using a JoinTable it will be in the join table. For an ElementCollection mapping it will be in the target table.

Example of a collection order column database

EMPLOYEE (table)
IDFIRSTNAMELASTNAMESALARY
1BobWay50000
2SarahSmith60000
EMPLOYEE_PHONE (table)
EMPLOYEE_IDPHONE_IDINDEX
110
131
220
241
PHONE(table)
IDAREACODENUMBER
1613792-7777
2416798-6666
3613792-9999
4416798-5555

Example of a collection order column annotation

@Entity
public class Employee {
  @Id
  private long id;
  ...
  @OneToMany
  @OrderColumn(name="INDEX")
  private List<Phone> phones;
  ...
}

Cascading


  • Relationship mappings have a cascade option that allows the relationship to be cascaded for common operations.
  • cascade is normally used to model dependent relationships, such as Order -> OrderLine.
  • Cascading the orderLinesrelationship allows for the Order's -> OrderLines to be persisted, removed, merged along with their parent.
 CascadeType enum:
  1. PERSIST - Cascaded the EntityManager.persist() operation. If persist() is called on the parent, and the child is also new, it will also be persisted. If it is existing, nothing will occur, although calling persist() on an existing object will still cascade the persist operation to its dependents. If you persist an object, and it is related to a new object, and the relationship does not cascade persist, then an exception will occur. This may require that you first call persist on the related object before relating it to the parent. General it may seem odd, or be desirable to always cascade the persist operation, if a new object is related to another object, then it should probably be persisted. There is most likely not a major issue with always cascading persist on every relationship, although it may have an impact on performance. Calling persist on a related object is not required, on commit any related object whose relationship is cascade persist will automatically be persisted. The advantage of calling persist up front is that any generated ids will (unless using identity) be assigned, and the prePersist event will be raised.
  2. REMOVE - Cascaded the EntityManager.remove() operation. If remove() is called on the parent then the child will also be removed. This should only be used for dependent relationships. Note that only the remove() operation is cascaded, if you remove a dependent object from a OneToMany collection it will not be deleted, JPA requires that you explicitly call remove() on it. Some JPA providers may support an option to have objects removed from dependent collection deleted, JPA 2.0 also defines an option for this.
  3. MERGE - Cascaded the EntityManager.merge() operation. If merge() is called on the parent, then the child will also be merged. This should normally be used for dependent relationships. Note that this only effects the cascading of the merge, the relationship reference itself will always be merged. This can be a major issue if you use transient variables to limit serialization, you may need to manually merge, or reset transient relationships in this case. Some JPA providers provide additional merge operations.
  4. REFRESH - Cascaded the EntityManager.refresh() operation. If refresh() is called on the parent then the child will also be refreshed. This should normally be used for dependent relationships. Be careful enabling this for all relationships, as it could cause changes made to other objects to be reset.
  5. ALL - Cascaded all the above operations.

Example of a cascaded one to one relationship annotations

@Entity
public class Employee {
  @Id
  private long id;
  ...
  @OneToOne(cascade={CascadeType.ALL})
  @JoinColumn(name="ADDR_ID")
  private Address address;
  ...
}

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.