Table of Contents
    JPA 2.0 specification introduces a new API to define queries dynamically
    via construction of an object-based
    javax.persistence.CriteriaQuery instance, rather
    than string-based approach used in JPQL (Java Persistence Query Language).
    This dynamic query definition capability, referred as Criteria API, is
    based on the abstract persistent schema of the entities, their embedded
    objects and their relationships. The syntax is designed to construct a
    Query Tree whose nodes represent the semantic query
    elements such as projections, conditional predicates of WHERE clause or
    GROUP BY elements etc.
    
The CriteriaBuilder interface is the factory for CriteriaQuery. A CriteriaBuilder is obtained from either an EntityManagerFactory or an EntityManager as follows:
EntityManager em = ... ;
CriteriaBuilder queryBuilder = em.getCriteriaBuilder();
CriteriaQuery qdef = queryBuilder.createQuery();
    	
    	The first step in constructing a query definition is specification of
    	query roots.  Query roots specify the domain objects on which the query
    	is evaluated. Query root is an instance of the Root<T> interface. A
    	query root is added to a CriteriaQuery by
    	addRoot(Class c) method.
    	
    	Root<Customer> customer = qdef.from(Customer.class);
    	
    	A query domain can be further refined by joining to other domain objects.
    	For example, for the above query definition to operate over customers
    	and their orders, use join(String attribute):
		
Root<Order> order = customer.join(customer.get(Customer_.orders));
where Customer_.orders represent a field of canonical metamodel class for Customer. These canonical metamodel classes are generated during compilation by processing the persistent annotation in the source code of Customer.java.
		The condition of a query definition is set via
		where(Predicate p) where the argument
		designates a conditional predicate. Conditional predicates are often
		composed of one or more comparisons between the attribute values of
		the domain objects and some variable. For example, to select the
		Customer whose name is "John Doe" and has
		orders that are not yet delivered, you can build the predicate and set
		it to the query definition as:
		
           qdef.where(customer.get(Customer_.name).equal("John Doe")
               .and(order.get(Order_.status).equal(OrderStatus.DELIVERED).not()));
		
		The select() method defines the result of the
		query. If left unspecified, the select projection is assumed to be the
		root domain object. However, you can specify the selected projections
		explicitly as a list:
		
            qdef.select(customer.get(Customer_.name), order.get(Order_.status));
		
    	An attribute of a domain object can also be specified by navigating via
		get(String attr). The attribute
		should refer
		to a valid persistent property of the receiving domain object, however
		no such validation is enforced during the construction of the query
		definition. All validation is deferred until the query is actually executed.
		On the other hand, using canonical metamodel for path navigate enforces
		compile type checking.