The Artima Developer Community
Sponsored Link

Artima Developer Spotlight Forum
Linda DeMichiel on the Type-Safe Criteria API in JPA 2.0

4 replies on 1 page. Most recent reply: Jan 26, 2010 2:26 PM by Timo Westkämper

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 4 replies on 1 page
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Linda DeMichiel on the Type-Safe Criteria API in JPA 2.0 Posted: Dec 17, 2008 9:58 PM
Reply to this message Reply
Advertisement

Since its introduction some two years ago, the Java Persistence API (JPA), originally part of the EJB 3.0 specification, has quickly become a popular mechanism to persist Java objects in relational databases. A key component of the JPA is its query language, JPQL.

While the JPQL significantly simplified working with persistent Java objects—for instance, by providing easy object navigation—JPQL queries are specified as Strings. Thus, while the queries themselves operate over strongly-typed Java objects, the query language relies on String-based expressions. Although some IDEs provide intelligent inspection of JPQL query expressions, JPQL still can't take advantage of many type-inspired coding features, such as robust refactoring.

Some O/R mapping frameworks, such as Hibernate, pioneered the use type-safe, criteria-based query APIs; in a recent blog post, Java Persistence 2.0 Public Draft: Criteria API, JSR 317 spec lead Linda DeMichiel explains how a similar criteria API is now part of the upcoming JPA 2.0 specification.

According to DeMichiel, the new criteria API is a "non-string-based API for the dynamic construction of object-based queries:"

Loosely speaking, a QueryDefinition object can be thought of as a set of nodes corresponding to the semantic constructs of the query:

  • Domain objects, which correspond to the range variables and other identification variables of the JPQL FROM clause
  • Where clause predicates, which comprise one or more conditional expression objects
  • Select clauses, which comprise one or more "select item" objects
  • Order-by and group-by items
  • Subqueries

DeMichiel explains that constructing queries with the new API starts similarly to how queries are currently built using JPQL, but then the two APIs diverge. An interesting point DeMichiel's examples highlight is the fluent interface of the Criteria API:

The specification of query roots is the first step in constructing a query definition. Query roots correspond to the range variables of SQL. They specify the domain objects on which the query is based and which are not reachable by navigation or join...

A query with a single root entity is assumed to select entities of that type, unless the select method of the QueryDefinition interface is used to specify otherwise. Thus, the DomainObject customer in the query above represents a complete query definition. We can pass it to the createQuery method and execute the resulting query, causing all instances of the Customer class to be returned:

Query q = em.createQuery(customer);
List myCustomers = q.getResultList();

[...] The addition of further query roots, like additional range variables in JPQL, has the effect of inducing a cartesian product.

What do you think of the new Criteria API in JPA 2.0?


Johannes Brodwall

Posts: 19
Nickname: jhannes
Registered: Jun, 2003

Re: Linda DeMichiel on the Type-Safe Criteria API in JPA 2.0 Posted: Dec 18, 2008 1:29 PM
Reply to this message Reply
After playing around with Mockito (http://code.google.com/p/mockito/), I think we can improve the type safety further by exchanging the DomainObject instances with proxies to the actual objects. Here's are some of the examples from the Public Draft by using dynamic proxies.

These examples compile and can, at least for these simple examples, organize the information correctly. What do you think, could this be an interesting addition to the proposal?

queryBuilder = new QueryBuilder();
Customer customer = queryBuilder.createQueryDefinition(Customer.class);
// NB: Not entirely pleased with this hack with collections
Item item = customer.getOrders().get(0).getItems().get(0);
queryBuilder.where(item.getProductType()).eq("printer")
        .select(customer.getName(), customer.getAddress());
 
queryBuilder = new QueryBuilder();
Employee employee = queryBuilder.createQueryDefinition(Employee.class);
queryBuilder.where(employee.getContactInfo().getAddress().getZipCode()).eq("95054")
    .where(employee.getContactInfo().getPhones().get(0).getPhoneType()).eq(PhoneType.OFFICE)
    .selectDistinct(employee.getContactInfo().getPhones().get(0).getBilledTo());
 
// Case syntax
queryBuilder = new QueryBuilder();
customer = queryBuilder.createQueryDefinition(Customer.class);
queryBuilder.caseExp()
    // Please note: The compiler would stop us if we said e.g. .gt("ten thousand")
    .when(customer.getAnnualSpending()).gt(10000.0).then("Premier")
    .when(customer.getAnnualSpending()).gt(5000.0).then("Gold")
    .when(customer.getAnnualSpending()).gt(200.0).then("Silver")
    .otherwise("Bronze");
 
// Compressed case syntax
queryBuilder = new QueryBuilder();
customer = queryBuilder.createQueryDefinition(Customer.class);
queryBuilder.caseExp(customer.getAnnualSpending())
    // Please note: The compiler stops us from saying e.g. gt("ten thousand")
    .when().gt(10000.0).then("Premier")
    .when().gt(5000.0).then("Gold")
    .when().gt(200.0).then("Silver")
    .otherwise("Bronze");

Carson Gross

Posts: 153
Nickname: cgross
Registered: Oct, 2006

Re: Linda DeMichiel on the Type-Safe Criteria API in JPA 2.0 Posted: Dec 18, 2008 4:40 PM
Reply to this message Reply
LINQ please: http://en.wikipedia.org/wiki/Language_Integrated_Query

Thanks,
Carson

Luis Matta

Posts: 6
Nickname: levmatta
Registered: Oct, 2004

Re: Linda DeMichiel on the Type-Safe Criteria API in JPA 2.0 Posted: Dec 22, 2008 12:28 PM
Reply to this message Reply
LINQ also started that way, the idea - as far as I know - is that if you like the API and enough people clame for the feature it can become a Java LINQ.

Timo Westkämper

Posts: 2
Nickname: timowestk
Registered: Nov, 2008

Re: Linda DeMichiel on the Type-Safe Criteria API in JPA 2.0 Posted: Jan 26, 2010 2:26 PM
Reply to this message Reply
Querydsl provides an alternative to the static metamodel of JPA 2 in the form of an APT generated dynamic metamodel.

The main benefit of a dynamic metamodel is that it can be used directly for path traversal and complex expression construction.

Here is an example


HibernateQuery qry = new HibernateQuery(session);
QCat cat = new QCat("cat"); // query variable
List<Cat> cats = q.from(cat).where(cat.name.between("A", "B")).list(cat);


In addition to JPA/Hibernate Querydsl supports also JDO, SQL and Java Collections.

http://source.mysema.com/display/querydsl/Querydsl

Flat View: This topic has 4 replies on 1 page
Topic: Software Development Has Stalled Previous Topic   Next Topic Topic: Working with Images in Flex 4

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use