Configure the WSJPA FastPath for improved performance
The Java Persistence API (JPA) is a very flexible specification that provides guidelines on how implementors are to translate relational data to Java object form. Due to the flexible nature of this API, a large amount of work is completed at runtime by the API provider to determine how to correctly load relational data into object form. This flexibility results in a runtime that, under certain circumstances, has to continually run redundant code to ensure that data is loaded properly. By giving up some of this flexibility, the WSJPA FastPath optimization attempts to skip much of this redundant code and generates highly optimized code that interacts directly with the JDBC layer.
Optimizing these code paths is a very complex process, and as such, not all domain models satisfy the requirements for WSJPA FastPath optimizations.
The Fastpath feature can improve the performance of some applications which have their data modeled in an acceptable format and are not using extended JPA features.
For example, review the following code:
public Customer findCustomer(int id) { return em.find(Customer.class, id); }
This example is a simple helper method that finds a customer entity. Every time the findCustomer method is invoked, the JPA runtime executes large amounts of code to analyze the request, to access the database, and to load the Customer Entity. Without the use of the FastPath optimization, most of the logic is identical for the second and subsequent executions of the findCustomer method. Very few of the runtime decisions from the first execution are retained for future invocations of the findCustomer method. This redundant code processing can cause performance issues for some scenarios.
When the FastPath feature is enabled, on the first invocation of em.find(Customer.class, id), highly optimized code is generated that replaces all subsequent calls to em.find(Customer, id). This generated code assumes that the only thing that might change is the id each time you find a Customer. As a result, we can generate nearly decision-free code. On the first method invocation, if FastPath generation is successful, a message similar to the following is logged:
10855 fp_pu INFO [main] FP - Successfully generated FastPath com.ibm.ws.persistence.fastpath.entities.Customer$Find$FastPath@1f6b69d7".
When this message is logged, all future executions of finding a Customer use this new generated path.
The previous example outlined how a finder path might be executed. FastPath also attempts to optimize lazy loading of fields (relationship and non-relationship) and executing NamedQueries.
Configure FastPath:
When persistence unit property wsjpa.FastPath=true is set, the JPA runtime attempts to determine which operations can be safely handled. The Include and Exclude properties can be used to explicitly configure which operations are executed using FastPath.
When wsjpa.FastPath is configured, openjpa.MetaDataRepository=Preload=true must also be configured. For example:
<property name="openjpa.MetaDataRepository" value="Preload=true"/>
In the event that a given path cannot be optimized by the FastPath runtime, or it is configured in the exclude property, it is executed by the normal JPA runtime code. This is a key feature that allows experimentation with the FastPath optimization. Any non-optimized code paths automatically falls back to the original JPA code path with no loss of function.
Configuration syntax :
<property name="wsjpa.FastPath" value="true(Include=’<path>;,<path>;...’;Exclude=’<path>,<path>...’)">Path syntax :
- Finder: <Fully qualified Entity name> (such as com.ibm.ws.jpa.Customer)
- Lazy loaded field: <Fully qualified field name> (such as com.ibm.ws.jpa.Customer.cars)
- Named query: <Full query name> (such as com.ibm.ws.jpa.customer_find_by_id)
Rules :
- If no properties(Include/Exclude) are specified, the runtime scans all persistent types and attempts to determine which paths can be processed.
- If the include property is specified, only the specified paths are processed and the exclude property is ignored.
- If the exclude property is specified, all paths attempt to be handled that are not in the exclude list.
- If a field is provided in the exclude list, and the fetch type for the field is EAGER, the field is ignored since the field would never by lazily loaded.
Example 1:
<property name="wsjpa.FastPath" value="false"/>
In this example, false is the default value; this optimization is not turned on by default.
Example 2:
<property name="wsjpa.FastPath" value="true"/>
The runtime processes all entities and attempts to determine which finders, lazy load operations, and named queries can be optimized.
Example 3:
<property name="wsjpa.FastPath" value="true(Exclude=com.ibm.ws.jpa.entities.Customer.address,customer.findById"/>
Same as in example #2, except lazy loading the Customer.address field and the named query customer.findById are excluded from FastPath processing.
Example 4:
<property name="wsjpa.FastPath" value="true(Include=com.ibm.ws.jpa.entities.Customer, customer.findById"/>
The only operations that are processed are finding a Customer and executing the NamedQuery ‘customer.findById’. All other operations are executed using the normal JPA runtime.
Limitations:
As stated previously, there are trade-offs to realize the full performance gains of using the FastPath optimizations. While this feature attempts to support a wide range of Entity models and JPA features, there are a number of known cases that are not supported by the FastPath optimization. Below is a list of the known limitations at this time:
- Incompatible with the openjpa.DataCache property.
- Incompatible with the openjpa.FetchPlan property.
- Passing a LockModeType and/or a map of properties into the EntityManager find method.
- Custom field strategies
@org.apache.openjpa.persistence.Factory, @javax.persistence.SecondaryTable,
@org.apache.openjpa.persistence.Externalizer,
@org.apache.openjpa.persistence.ExternalValues,
@org.apache.openjpa.persistence.LRS, @java.sql.Lob, @java.sql.Clob, @java.sql.Blo
- XML Column Mapping
- Embeddables
- Only single table inheritance is supported.
- @javax.persistence.PostLoad callback
- Delimited identifiers
- Executing a path which results in :
- Fetching a ManyToMany field.
- Fetching a collection which is implemented as a Map, or Array.
- Execution of a SQL statement that results in joining on a join table
- Execution of a SQL statement that results in joining on the same table more than once. ie: Having an Entity which has multiple EAGER OneToOne relationships to the same Entity.
- Loading multiple levels of eager relationships. Such as {A->(eager)B->(eager)C}
- Calling the following methods setFirst, setFlush, setHind, setLockMode, and setMax on a NamedQuery.
- Incompatible with JPA applications that use PureQuery.
- Incompatible with JPA applications that use access intent.
- Set any property at runtime that changes how JPA fetches data.
Related tasks
Default Java Persistence API settings Configure persistence provider support in the application server Use third-party persistence providers Configure the JPA default persistence provider Configure the default JTA and non-JTA data source JNDI names