Oracle recently released version 2.2 of the Java Persistence API (JPA), which is the standard for persisting Java objects to a relational database.
As a part of the Java EE 8 platform, JPA 2.2 includes support for streaming query results, injecting managed beans into attribute converters, repeating annotations, and working with classes in the Java 8 Date and Time API. Although the changes are few, they are significant because JPA 2.2 is the first version that takes Java 8 as a baseline.
Josh Juneau, in his article (in the Nov / Dec 17 issue of Java Magazine), "What's New in JPA 2.2" remarked:
At last, JPA is brought into alignment with Java SE 8, allowing developers to make use of features such as Date and Time API, streaming query results, and repeatable annotations.
Streaming query results
The getResultStream()
method was added to both the Query
and TypedQuery
interfaces; this improvement returns a stream of results, providing a convenient way to work with data. Prior to JPA 2.2 only lists were returned from a query. The new streaming methods can be used like this:
Stream<Stock> stocks = entityManager
.createNamedQuery(Stock.FIND_HIGH_PERFORMERS, Stock.class)
.getResultStream();
stocks.filter(...)
Streams help queries perform better; however, in some cases, ResultSet
pagination may perform better when working with large datasets. There are some persistence providers that take this performance hit into consideration by providing a better implementation of getResultStream()
. Developers should consider performance when using streams with large datasets.
Injectable attribute converters
JPA 2.2 introduces the ability to inject managed beans into attribute converters using Contexts and Dependency Injection (CDI)'s @Inject
annotation. To utilize this feature, inject CDI resources into any attribute converter, as needed.
@Converter(autoApply = true)
public class TheAttributeConverter implements AttributeConverter<TheObject, String> {
@Inject
private MyUtils utils;
@Override
public TheObject convertToEntityAttribute(String s) {
return utils.toTheObject(s);
}
@Override
public String convertToDatabaseColumn(TheObject obj) {
return utils.toString(obj);
}
}
Repeatable annotations
All annotations for which there exists a container annotation are now repeatable, which allows for multiple instances of the same annotation on a class, method, or attribute. With JPA 2.2, the following annotations are repeatable:
AssociationOverride
AttributeOverride
Convert
JoinColumn
MapKeyJoinColumn
NamedEntityGraph
NamedNativeQuery
NamedQuery
NamedStoredProcedureQuery
PersistenceContext
PersistenceUnit
PrimaryKeyJoinColumn
SecondaryTable
SqlResultSetMapping
This improvement eliminates the need to use container annotations, making code easier to read, and allowing constructions such as:
@Entity
@NamedQuery(name = "Stock.findBySymbol", query = "SELECT s FROM Stocks s WHERE s.symbol = :symbol")
@NamedQuery(name = "Stock.findByDate", query = "SELECT s FROM Stocks s WHERE s.date = :date")
@NamedQuery(name = "Stock.findByPrice", query = "SELECT s FROM Stocks s WHERE s.price = :price")
public class Stock {
...
}
Java 8 date and time support
JPA 2.2 provides basic support for Java 8 date and time types and includes the following mappings for classes in java.time
:
LocalDate
LocalTime
LocalDateTime
OffsetTime
OffsetDateTime
Unlike previous versions of JPA, there is no longer a need to write attribute converters to perform mapping from database date and time types to Java 8 date and time types (and vice versa). Because support is built in for the Java Date and Time API, there is no extra work required to use the five supported types and they simply slot in to the existing API:
@Entity
public class Stock implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", updatable = false, nullable = false)
private Long id;
@Column(name="LAST_BUY_DATE")
private LocalDate lastBuyDate;
@Column(name="LAST_BUY_TIME")
private LocalDateTime lastBuyTime;
}
Since these improvements are a part of the Java EE 8 platform, only compliant application servers provide them out of the box. However, earlier Java EE versions can access them by simply including the applicable JAR files in the project.
More details can be found in the release notes for the Java Persistence 2.2 maintenance release.