8 New Functionalities in JPA 2.1 and Bean Validation 1.1

As in the previous chapters, this last section will address some of the new functionalities available in Java EE 7. Specifically, these are a few minor innovations thaat are not used in our sample application but which are worth knowing about nevertheless.

8.1 Bean Validation At The Method Level

The authors have found bean validation at the method level to be an interesting development in Java EE with regards to JPA and Bean Validation.

In section 6, we learned about how conditions of attributes can be upheld and validated using annotations. With Bean Validation 1.1, this can also be carried out for the parameters and return values of methods. There is currently no good opportunity to use it in our sample application. Because of this, we’ll study the following method for creating a donation with parameters:

@NotNull
public Donation createSpende(Long campaignId,
    @Size(min=5, max=40) String donorName,
    @DecimalMin(value="1.00") Double amount,
    @Pattern(regexp="[A-Z]{2}[0-9]{2}[A-Z0-9]{12,30}") String iban,
    @Size(min=4, max=40) String nameOfBank) {...

The method creates a Donation object using the specified parameters. The annotations from the Bean Validation API serve to ensure that the input parameters correspond to the technical conditions of a Donation object and that a non-empty Donation object (via the annotation @NotNull) is returned.

8.2 Extended CDI Support

In section 7.4, we learned about the concept of the EntityListener. With JPA 2.1, we are able to inject it with CDI beans. If we look at the example from the section once more, we see that we can use @Inject to insert the logger from the class Resources in the DateUpdateEntityListener. The callback method of the EntityListener can then use methods in the logger for several functions, including recording the invocation of the method in a log file.

Likewise, the Bean Validation API benefits from extended CDI support. By the time of Bean Validation 1.0, it was already possible to create custom conditions; this was achieved by implementing a class as it stands with the interface ConstraintValidator. The only new feature is the the implementation can now inject CDI beans.

8.3 Invoking Stored Procedures and Functions

Virtually every database supports so-called “stored procedures”. These are methods that are executed directly on the database server instead of on the application server. Database systems usually provide these stored procedures with their own languages, such as the PL/SQL[1] language used for Oracle databases. For this reason, stored procedures are not easy to migrate to other database systems.

Their advantage, however, lies in their frequently greater execution speed, since less data must be exchanged between the application and database servers than for the execution of a Java method.

Stored procedures are therefore normally used for processing larger amounts of data, such as within a background job.

Before JPA 2.1, there was no standard for invoking stored procedures. JPA 2.1 made it possible – in the same way as with NamedQueries – to create a so-called NamedStoredProcedureQuery for invoking a stored procedure. In the following example, a special query of this kind is defined and can then be used to start a stored procedure with the name doBackgroundJob:

@Entity
@NamedStoredProcedureQuery(name="backgroundJob", procedureName="doBackgroundJob")
public class Something { ...

The NamedStoredProcedureQuery that is created can then be resolved with the identifier backgroundJob using the EntityManager:

StoredProcedureQuery query = entityManager.createNamedStoredProcedureQuery("backgroundJob");

We will obtain the object query of the type StoredProcedureQuery as a return value. Then, we can add parameters for the invocation of the Stored Procedure before invoking it with the method execute. The following example uses the integer parameter  20:

query.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN);
query.setParameter(1, 20);
query.execute();

Alongside Stored Procedures, database systems also support the development of custom functions. In Oracle, these are also created using PL/SQL. JPA 2.1 supports the invocation of such functions within JPQL queries as one of its new functions. To accomplish this, the keyword FUNCTION is used within the request.

Let’s suppose there is a database function with the name validIban that determines whether a certain IBAN is valid. In this case, the following expression could be used to select all campaigns with a valid IBAN:

SELECT c FROM CAMPAIGN c WHERE FUNCTION(‘validIban’, c.account.iban)

8.4 Bulk Write Operations With The Criteria API

Even before JPA 2.1, it was possible to edit multiple data sets simultaneously using a JPQL query. In the following simple example, the donation goal is set to 1,000 euros for all campaigns with a minimum donation amount of 10 euros:

UPDATE CAMPAIGN AS c SET c.targetAmount = 1000.00 WHERE c.donationMinimum > 10.00

Such bulk write operations are only possible with the Criteria API. To implement our example, we first of all require an instance of the class CriteriaUpdate, which is created for a Campaign object using the CriteriaBuilder cb as follows:

CriteriaUpdate<Campaign> q = cb.createCriteriaUpdate(Campaign.class);

We can set the desired query on this object as follows:

Root<Campaign> c = q.from(Campaign.class);
q.set(c.get("targetAmount"), 1000.00).where(cb.gt(c.get("donationMinimum"), 10.00));

Next, the resulting query can be executed as normal using the EntityManager:

Query query = entityManager.createQuery(q);
query.executeUpdate();

Discussion

Use the message board below to give the authors your feedback or to discuss this page’s topic with other readers (in English please!). Please don’t expect the authors to answer directly, but they might update the content of this site according to your feedback.