JPA 2.1 performance tuning tips

17
Osama Oransa osama-oransa.blogspot.com

description

For More information, refer to Java EE 7 performance tuning and optimization book: The book is published by Packt Publishing: http://www.packtpub.com/java-ee-7-performance-tuning-and-optimization/book

Transcript of JPA 2.1 performance tuning tips

Page 1: JPA 2.1 performance tuning tips

Osama Oransa

osama-oransa.blogspot.com

Page 2: JPA 2.1 performance tuning tips

Use the proper loading strategy from either lazy loading or eager data loading according to our data size and usage; for small data volume, eager loading always make sense.

Query results pagination is also an important JPA feature. The importance of this feature is to avoid memory issues when the returned data is huge.

The JPA provides two methods to control this pagination: setMaxResults(int maxResult) and setFirstResult(int startPosition) in the Query object.

Page 3: JPA 2.1 performance tuning tips

Use data chunking to return the required data only from the database side, instead of filtering in the application side using the IN keyword and adding the list of IDs to the query.

Increasing the index pre-allocation size can speed up the creation of new objects. Also try to minimize the usage of composite primary keys for different entities.

Page 4: JPA 2.1 performance tuning tips

Enabling entity caching is important to improve the performance.

Enable the query-level caching for better performance. One way to do that is by adding a hint to the named query as follows:◦ hints={@QueryHint(name="eclipselink.query-

results-cache", value="true")}

Page 5: JPA 2.1 performance tuning tips

Use batch interaction by sending a group of inserts/updates/deletes to the database in a single transaction by setting "eclipselink.jdbc.batch-writing"="JDBC" in persistence.xml, we can also specify the size of the batch using another property, "eclipselink.jdbc.batch-writing.size"="2000".

Use the read-only entities when the entities are not going to be modified, such as entities for lookup data (for example, e-mail templates). ◦ This can be done using the @ReadOnly annotation on

the level of the entity.

Page 6: JPA 2.1 performance tuning tips

Access the JPA from stateless session beans as a façade layer to get benefits from different resource injections and EJB transactional and security handling, and encapsulate all JPA access logic.

Don’t put (or minimize) any business logic in Entity setters and getters.

Page 7: JPA 2.1 performance tuning tips

The shared-cache-mode element in the persistence.xml deployment descriptor.<persistence-unit name="examplePU" transaction-

type="JTA">

<provider>org.eclipse.persistence.jpa.PersistenceProvider

</provider>

<jta-data-source>jdbc/__default</jta-data-source>

<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

</persistence-unit>

Page 8: JPA 2.1 performance tuning tips

Cache retrieval mode, set by the javax.persistence.retrieveMode property, controls how data is read from the cache for calls to the EntityManager.find method and from queries.

The retrieveMode property can be set to one of the constants defined by the javax.persistence.CacheRetrieveMode enumtype, either USE (the default) or BYPASS. ◦ USE, data is retrieved from the second-level cache, if

available. If the data is not in the cache, the persistence provider will read it from the database.

◦ BYPASS, the second-level cache is bypassed and a call to the database is made to retrieve the data.

Page 9: JPA 2.1 performance tuning tips

The cache store mode, set by the javax.persistence.storeMode property, controls how data is stored in the cache.

The storeMode property can be set to one of the constants defined by the javax.persistence.CacheStoreMode enumerated type, either:◦ USE (the default)◦ BYPASS◦ REFRESH

Example:EntityManager em = ...; em.setProperty("javax.persistence.cache.storeMode",

"BYPASS");

Page 10: JPA 2.1 performance tuning tips

USE the cache data is created or updated when data is read from or committed to the database. ◦ If data is already in the cache, setting the store mode

to USE will not force a refresh when data is read from the database.

BYPASS, data read from or committed to the database is not inserted or updated in the cache. ◦ That is, the cache is unchanged.

REFRESH, the cache data is created or updated when data is read from or committed to the database, and a refresh is forced on data in the cache upon database reads.

Page 11: JPA 2.1 performance tuning tips

EntityManager em = ...;

Map<String, Object> props = new HashMap<String, Object>();

props.put("javax.persistence.cache.retrieveMode", "BYPASS");

String personPK = ...;

Person person = em.find(Person.class, personPK, props);

Page 12: JPA 2.1 performance tuning tips

EntityManager em = ...;

CriteriaQuery<Person> cq = ...;

TypedQuery<Person> q = em.createQuery(cq);

q.setHint("javax.persistence.cache.storeMode", "REFRESH");

Page 13: JPA 2.1 performance tuning tips

EntityManager em = ...;

Cache cache = em.getEntityManagerFactory().getCache();

String personPK = ...;

if (cache.contains(Person.class, personPK)) {

// the data is cached

} else {

// the data is NOT cached

}

Page 14: JPA 2.1 performance tuning tips

EntityManager em = ...;

Cache cache = em.getEntityManagerFactory().getCache();

cache.evict(Person.class, personPK);

cache.evictAll();

Page 15: JPA 2.1 performance tuning tips

Many metadata annotations in JPA have a fetch property. This property can take on one of two

values: FetchType.EAGER or FetchType.LAZY. FetchType.EAGER means that the field is loaded by the JPA

implementation before it returns the persistent object to you. ◦ Whenever you retrieve an entity from a query or from

the EntityManager, you are guaranteed that all of its eager fields are populated with datastore data.

FetchType.LAZY is a hint to the JPA runtime that you want to defer loading of the field until you access it. ◦ This is called lazy loading. Lazy loading is completely transparent; ◦ When you attempt to read the field for the first time, the JPA

runtime will load the value from the datastore and populate the field automatically.

◦ Lazy loading is only a hint and not a directive because some JPA implementations cannot lazy-load certain field types.

Page 16: JPA 2.1 performance tuning tips

With a mix of eager and lazily-loaded fields, you can ensure that commonly-used fields load efficiently, and that other state loads transparently when accessed.

Example:@OneToOne(fetch=FetchType.LAZY)

private Article article;