Enterprise Java Development@TOPIC@

JPA Queries

Revision: v2013-10-08

Built on: 2014-03-07 00:09 EST

Abstract

This presentation provides information covering JPA Queries, JPA Query Language, and the JPA Criteria API.


Purpose
1. Goals
2. Objectives
I. General Queries
1. JPA Query Types
1.1. JPA Query Language (JPA-QL) Queries
1.2. Native SQL Queries
1.3. Criteria API Queries
1.4. Strongly Typed Queries
1.4.1. Metamodel API
1.4.2. Query using JPA Metamodel
1.4.3. Canonical Metamodel
1.4.4. Generating Canonical Metamodel Classes
1.5. Summary
2. JPA Query Overview
2.1. EntityManager Query Methods
2.2. Query.getSingleResult()
2.3. Query.getResultList
2.4. Parameters
2.5. Paging Properties
2.6. Pessimistic Locking
2.7. Bulk Updates
2.8. Named Queries
2.9. Summary
II. JPAQL
3. JPA Query Language
3.1. Simple Entity Query
3.2. Non-Entity Queries
3.3. Multi-select Query
3.3.1. Multi-select Query with Object[]
3.3.2. Multi-select Query with Tuple
3.3.3. Multi-select Query with Constructor
3.4. Path Expressions
3.4.1. Single Element Path Expressions
3.4.2. Collection Element Path Expressions
3.5. Eager Fetching through JOINs
3.5.1. Lazy Fetch Problem
3.5.2. Adding Eager Fetch during Query
3.6. Distinct Results
3.7. Summary
4. JPAQL Where Clauses
4.1. Equality Test
4.2. Like Test
4.3. Formulas
4.4. Logic Operators
4.5. Equality Tests
4.6. Between
4.7. Testing for Null
4.8. Testing Empty Collection
4.9. Membership Test
4.10. Subqueries
4.11. All
4.12. Any
4.13. Summary
5. JPAQL Functions
5.1. String Functions
5.1.1. Base Query
5.1.2. LOWER
5.1.3. UPPER
5.1.4. TRIM
5.1.5. CONCAT
5.1.6. LENGTH
5.1.7. LOCATE
5.1.8. SUBSTRING
5.2. Date Functions
5.3. Order By
5.4. Aggregate Functions
5.4.1. COUNT
5.4.2. MIN/MAX
5.4.3. SUM/AVE
5.5. Group By
5.6. Having
5.7. Summary
III. Criteria API
6. JPA Criteria API
6.1. Criteria API Demo Template
6.2. Simple Entity Query
6.3. Non-Entity Query
6.4. Multi-select Query
6.4.1. Multi-select Query with Object[]
6.4.2. Multi-select Query with Tuple
6.4.3. Multi-select Query with Constructor
6.5. Path Expressions
6.5.1. Single Element Path Expressions
6.5.2. Collection Element Path Expressions
6.6. Eager Fetching through JOINs
6.6.1. Lazy Fetch Problem
6.6.2. Adding Eager Fetch during Query
6.7. Distinct Results
6.8. Summary
7. Criteria Where Clauses
7.1. Equality Test
7.2. Like Test
7.2.1. Like Test Literal
7.2.2. Like Test Literal Parameter
7.2.3. Like Test Concatenated String
7.2.4. Like Test Single Character Wildcard
7.3. Formulas
7.4. Logic Operators
7.5. Equality Tests
7.6. Between
7.7. Testing for Null
7.8. Testing Empty Collection
7.9. Membership Test
7.10. Subqueries
7.11. All
7.12. Any
7.13. Summary
8. Criteria Functions
8.1. String Functions
8.1.1. Base Query
8.1.2. LOWER
8.1.3. UPPER
8.1.4. TRIM
8.1.5. CONCAT
8.1.6. LENGTH
8.1.7. LOCATE
8.1.8. SUBSTRING
8.2. Date Functions
8.3. Order By
8.4. Aggregate Functions
8.4.1. COUNT
8.4.2. MIN/MAX
8.4.3. SUM/AVE
8.5. Group By
8.6. Having
8.7. Summary

Three fundamental query types within JPA

  • JPA Query Language (JPA) - entity/property/relationship-based

  • Native SQL - table/column-based

  • Criteria API - entity/property/relationship-based using Java classes


  • "c" is part of root query

  • "c" represents rows from Customer entity table(s)

  • "c.lastName" is path off root term

  • ":firstName" is parameter placeholder

  • "c.firstName" is path off root term

  • "Customer.class" type parameter allows for a type-safe return result


  • Placeholder is replaced by runtime parameter

  • Zero-or-more results are requested

  • Entities returned are managed



  • "c" represents rows in table

  • specific columns (or *) are return for each row

  • "?" marks a positional parameter -- non-portable to use named parameters in native SQL queries

  • TypedQuery<T>s not supported in native SQL queries because of a conflict with legacy JPA 1.0 API


  • Query execution similar to other query types

  • User-provided SQL executed

Note

Legacy JPA 1.0 Native SQL query syntax already used the signature of passing in a Class for createNativeQuery(). In this context, it was an entity class that contained JPA mappings for the query -- not the returned entity type. This prevented createNativeQuery() from being updated to return a typed result in JPA 2.0.



  • "CriteriaBuilder" used as starting point to build objects within the query tree

  • "CriteriaQuery<T>" used to hold the definition of query

  • "Root<T>" used to reference root level query terms

  • "CriteriaBuilder.from()" used to designate the entity that represents root query term

    • Result used to create path references for query body

  • "CriteriaBuilder.select()" officially lists the objects returned from query

  • "CriteriaBuilder.where()" builds a decision predicate of which entities to include

  • "CriteriaBuilder.equal()" builds an equals predicate for the where clause

  • "Root<T>.get()" returns the property referenced in path expression

  • "CriteriaBuilder.parameter()" builds a parameter placeholder within query. Useful with @Temporal date comparisons


  • Query execution identical to JPA-QL case



  • Access to properties within entities done through type-safe accessors


  • Results identical to previous approaches



  • Construct or generate a canonical metamodel class to provide type-safe, easy access to properties


  • Use canonical metamodel class to provide type-safe, easy access to properties ("Customer_.firstName")


  • Result is identical to previous approaches


  • More work to get here but clean, result

  • Type-safe - queries will not compile if entity changes





  • :firstName and :lastName act as placeholders for runtime query parameters

  • Runtime parameters supplied using placeholder names

  • A parameter for each placeholder must be supplied - no defaults

  • A placeholder must exist for each parameter supplied - no extras


  • Appended numbers (?1) assign an ordinal value

  • No numbers supplied (?) cause default value based on order


  • Dates are specified as DATE, TIME, or TIMESTAMP


  • Change directly applied to database, not the cached entity

  • Number of entities changed returned


  • Bulk deletes do not trigger cascades

  • Entity instance exists in memory even after deleted from database


  • Keeping stale entities around will produce confusing results

  • "em.clear()" should be avoided except at end of transaction since un-manages everything




  • Example query uses Native SQL to return all columns for table



  • Individual elements of select are matched up against class constructor


  • Constructed class may be simple POJO -- no need to be an entity

  • Instances are not managed

  • Suitable for use as Data Transfer Objects (DTOs)


  • Each row returned as instance of provided class


  • A normal JOIN (implicit or explicit) may honor the fetch=LAZY property setting of the relation

  • Can be exactly what is desired

  • Can also cause problems or extra work if not desired


  • Sales are lazily fetched when obtaining Store


  • Accessing the Sale properties causes a LazyInitializationException when persistence context no longer active or accessible

One Row per Parent is Returned for fetch=LAZY

Note that only a single row is required to be returned from the database for a fetch=LAZY relation. Although it requires more queries to the database, it eliminates duplicate parent information for each child row and can eliminate the follow-on query all together when not accessed.








  • Compare entities and not primary/foreign key values


Can be used to determine membership in a collection


  • Defines a shorthand for a subquery




  • List all clerks that have all sales above $125.00 or none at all

  • -or- List all clerks with no sale <= $125.00


  • Manny excluded because has 1 sale below $125.00

  • Moe included because has only $150.00 sale

  • Jack included because has no sales that fail criteria


  • List all clerks that have all sales below $125.00 or none at all

  • -or- List all clerks with no sale >= $125.00


  • Manny excluded because has 1 sale above $125.00

  • Moe excluded because has only $150.00 sale

  • Jack included because has no sales that fail criteria


  • List all clerks that have at least one sale above $125.00


  • Manny included because has 1 sale above $125.00

  • Moe included because $150.00 sale qualifies him as well

  • Jack excluded because has no sales that meet criteria


  • List all clerks that have at least one sale below $125.00


  • Manny included because has 1 sale below $125.00

  • Moe excluded because his only $150.00 sale above criteria

  • Jack excluded because has no sales that meet criteria


  • Located two Sales that occurred prior to today's date


  • Located no sales on today's date


  • Update all sales to today


  • Now locating sales for today's date

Note

Bulk commands (i.e., update) invalidate cached entities. You must refresh their state with the database or detach/clear them from the persistence context to avoid using out-dated information.



  • Aliases may be assigned to select terms for named-access to results


  • Query defined to return instances of Tuple class

  • Tuples provide access using

    • get(index) - simular to Object[]

    • get(index, Class<T> resultType) - typed access by index

    • get(alias) - access by alias

    • get(alias, Class<T> resultType) - typed access by alias

    • getElements() - access thru collection interface




  • Individual elements of select() are matched up against class constructor


  • Constructed class may be simple POJO -- no need to be an entity

  • Instances are not managed

  • Suitable for use as Data Transfer Objects (DTOs)




  • All paths based off root-level FROM (or JOIN) terms

  • Paths use call chaining to change contexts

  • Paths -- used this way -- must always express a single element. Must use JOINs for paths involving collections

  • All paths based off root-level FROM (or JOIN) terms



  • Automatic INNER JOIN formed between Sale and Store because of the cross-entity path



  • A normal JOIN (implicit or explicit) may honor the fetch=LAZY property setting of the relation

  • Can be exactly what is desired

  • Can also cause problems or extra work if not desired


  • Sales are lazily fetched when obtaining Store


  • Accessing the Sale properties causes a LazyInitializationException when persistence context no longer active or accessible


One Row per Parent is Returned for fetch=LAZY

Note that only a single row is required to be returned from the database for a fetch=LAZY relation. Although it requires more queries to the database, it eliminates duplicate parent information for each child row and can eliminate the follow-on query all together when not accessed.













  • Compare entities and not primary/foreign key values



Can be used to test for an empty collection




  • Sub-select returns values from collection under test

  • Outer query tests for no existing (EMPTY)values




  • Sub-select returns values from collection under test

  • Outer query tests for existing (NOT EMPTY)values

Can be used to determine membership in a collection



  • Defines a shorthand for a subquery





  • List all clerks that have all sales above $125.00 or none at all

  • -or- List all clerks with no sale <= $125.00


  • Manny excluded because has 1 sale below $125.00

  • Moe included because has only $150.00 sale

  • Jack included because has no sales that fail criteria



  • List all clerks that have all sales below $125.00 or none at all

  • -or- List all clerks with no sale >= $125.00


  • Manny excluded because has 1 sale above $125.00

  • Moe excluded because has only $150.00 sale

  • Jack included because has no sales that fail criteria



  • List all clerks that have at least one sale above $125.00


  • Manny included because has 1 sale above $125.00

  • Moe included because $150.00 sale qualifies him as well

  • Jack excluded because has no sales that meet criteria



  • List all clerks that have at least one sale below $125.00


  • Manny included because has 1 sale below $125.00

  • Moe excluded because his only $150.00 sale above criteria

  • Jack excluded because has no sales that meet criteria




  • Located two Sales that occurred prior to today's date




  • Located no sales on today's date



  • Update all sales to today

JPA Criteria API does not Provide Bulk Updates

JPA provides no mechanism to perform bulk updates with Criteria API. You must use JPAQL or SQL to perform bulk updates.




  • Now locating sales for today's date

Note

Bulk commands (i.e., update) invalidate cached entities. You must refresh their state with the database or detach/clear them from the persistence context to avoid using out-dated information.