Book Image

Java EE 7 Developer Handbook

By : Peter A. Pilgrim
Book Image

Java EE 7 Developer Handbook

By: Peter A. Pilgrim

Overview of this book

<p>The seventh edition of the Enterprise Java platform is aimed at helping Java engineers take advantage of the advancements in HTML5 and web standards. Web Sockets, asynchronous input and output with Servlets, and strong type safety through the CDI containers will ensure that Java EE 7 remains popular for server-side applications.<br />If you are a user aiming to get acquainted with the Java EE 7 platform, this book is for you.</p> <p>"Java EE 7 Developer Handbook" provides a solid foundation of knowledge for developers to build business applications. Following the lead of Agile practices, there is a focus on writing tests to demonstrate test-driven development principles, using the embedded GlassFish 4.0 container examples and the Gradle build system. You will learn about CDI, EJB, JPA, JMS, MDB, Servlets, WebSocket, JAX-RS, Bean Validation, and so much more.</p> <p>"Java EE 7 Developer Handbook" is designed as a companion to the professional software developer who quickly needs to lookup some working code, understand the basics of the framework, and then go out and fulfill the business contract with the customer. Typically, engineers are under pressure to develop professional code that is of high quality and contains a low number of bugs. Java EE 7 Developer Handbook relies heavily on the Arquillian framework to illustrate how much easier it is to write Java EE tests, and together with the modern practice of writing containerless applications that actually embed an application container, developing agile Java EE suddenly becomes reasonable, smart, pragmatic, and achievable.</p> <p>You will start off with an overview of the Java EE platform: the containers, the design, and architecture. From there, you can follow the path of the CDI, the true gem of the framework, and then the server side end point, EJB. It is completely up to you when and if you want to learn about Java persistence. However, don’t miss out on the highlights of Java EE 7 such as WebSocket, Bean Validation, and asynchronous Servlet API.</p> <p>"Java EE 7 Developer Handbook" is a vertical slice through standard Java enterprise architecture. If you have been wondering why developers have invested so much time and effort into learning topics such as Enterprise Java Beans, you will quickly understand why when you find out the difference between stateful and stateless Beans. Best of all, this book covers the topic from the perspective of new API and new modern practices. For instance, you, the developer and designer, are expected to write applications with annotations in comparison with J2EE. Java EE 7 Developer Handbook incorporates helpful hints and tips to get the developer up to speed in a short amount of time on EJB, CDI, Persistence, Servlet, JMS, WebSocket, JAX-RS and Bean Validation, and much more.</p> <p>"Java EE 7 Developer Handbook" is the reference guide you need beside you at your desk.</p>
Table of Contents (23 chapters)
Java EE 7 Developer Handbook
Credits
About the Author
Acknowledgment
About the Reviewers
www.PacktPub.com
Preface
Index

Transactions and concurrency


Persistence units encapsulate the object-relational mapping to the database. This section is about how they encounter transactions, concurrency, and multiple requests.

Entity managers

Here are some helpful rules about javax.ejb.EntityManager:

  • Prefer to inject EntityManager as a dependency in a Java EE application. Therefore, the application server takes care of its lifecycle and the responsibility to close the persistence unit. Use @PersistenceContext.

  • Do not cache or store in between requests: The EntityManager instance is not thread-safe.

  • The EntityManager instance manually retrieved from EntityManagerFactory must be closed in a retrieval method request for that particular state lest it goes out of scope, escapes, and potentially becomes a memory leak.

  • An EntityManager that represents a JTA data source must be associated with a transaction by calling the joinTransaction() method. This is particularly true in a Java EE 6 web container.

  • Obtain UserTransaction through dependency injection and remember to call begin() and end() to demarcate the transaction boundaries. The only exceptions to this rule are persistence units that are explicitly bound with Synchronization.UNSYNCHRONIZED.

  • Do use EntityManagerFactory to look up the persistence context in a Java SE application. The factory, definitely, is thread-safe.

  • Do close the EntityManager instance with a final clause in Java SE application. Sadly the interface cannot yet be made both AutoClosable with Java SE 7 and also retrospectively compatible with Java SE 5 or 6.

Transactions, entity managers, and session EJBs

Inside a Java EE environment, EntityManager is configured with a transaction by default. It can either be PersistenceContextType.TRANSACTION or PersistenceContextType.EXTENDED. The extended variety can only be injected into stateful session EJBs.

Transactions are demarcated on session EJB methods, which by default are set for TransactionAttribute.REQUIRED. Developers can explicitly annotate methods with TranactionAttribute.SUPPORTS or TranactionAttribute.MANDATORY, but this is normally unnecessary. In a Java EE application, a transaction-able method in a session EJB will be associated with the EntityManager object instance by default.

During operations in TRANSACTION mode, the application server will take responsibility for transactions in this scenario. The entities attached to the persistence unit are alive for the entire duration of the transaction. Once the method ends normally (or abnormally) the transaction is completed. The entities are detached from the persistence unit. When the entities are detached, then any changes to them are not synchronized to a database.

Transactions associated with entity managers can survive through nested invocations of other reference EJB calls, assuming that they permit and support transactions. This is called Transaction Propagation. All JPA entities remain intact and attached to the current entity manager.

Here is the table that summarizes the different cases of EntityManager for manual operation, in a stateless and stateful session bean.

Modus Operandi

Manual Creation

Stateless Session Bean

Stateful Session Bean

EntityManager

Thread-unsafe

Thread-unsafe

Thread-unsafe

EntityManagerFactory

Thread-safe

N/A

N/A

Responsibility for releasing

Developer must close in a final block

N/A

N/A

Multiple thread capabilities (concurrency access)

Developer takes responsibility

EJB container and application server take control

EJB container is in control

UserTransaction association

Developer must demarcate manually and also use @Inject UserTransaction

Automatic with dependency injection (DI)

Automatic with dependency injection (DI)

What happens to EntityManager after the end of the current transaction call?

Developer must guarantee EntityManager is closed

Automatically call close() after the end of transaction method call

Automatic closure for TRANSACTION mode or continuation of lifetime EXTENDED transaction mode

Lifetime of entities in the current EntityManager

Developer decides when to commit() or rollback()

Entities are detached after the transaction method call completes

Remain attached to the manager until the EJB is removed by caller

Cascade of transaction through EJB reference (Transaction propagation)

N/A

Yes (with internal cache of entities)

Yes (with client specific cache of entities)

Domain objects or detached entities serialized from an EJB client

Entities must be manually merged with EntityManager

Entities must be manually merged with EntityManager

For EXTENDED transaction mode, entities are never detached

The abbreviation N/A stands for Not Applicable.

EntityManager has methods that require an active transaction: persist(), merge(), remove(), refresh(), and flush(). If there is no associated current transaction then these methods will raise a TransactionRequiredException.

Stateful session beans

Stateful session beans are a special case of EntityManager when they are used in the extended persistence unit situation PersistenceContextType.EXTENDED. Entities remain attached and synchronized with the entity manager during interactions between the caller and the EJB.

In a web application this 1:1 relationship requires some thought and logic as the long-lived entities will stick around in a client specific cache of instances. In a long conversation, this behavior may be problematic, because the managed entities are not visible out of the transaction. The changes to the database are buffered inside the entity manager. In order to get the changes reflected in the database, it may be necessary to invoke the EntityManager.flush() method at certain intervals. Of course, this will affect the ability to roll back to the beginning of the conversation and could be the bane of Java database development: lost updates seen by another user.

Because of the client specific cache of stateful session bean, we strongly recommend avoiding concurrency access with the same caller.

The managed entities will be attached until the caller invokes the stateful session bean's removal operation, which causes its dissociation from the caller and only then will the entity manager synchronize instance with the database and then detach the entities.

Concurrency access locks

JPA supports both optimistic and pessimistic locking facilities. By default, JPA updates rows in a database table using optimistic locking.

Optimistic locking

Optimistic locking is a lenient strategy for dealing with concurrency access to shared entities held by EntityManager. With this strategy, which tends to scale better than pessimistic locking, the application can retrieve the data, make some changes to it, and write it to the database. Data version validation is performed during the write phase to the database.

To provide optimistic locking of entity in JPA, annotate a field or property with the @Version constraint. Preferably use an integer field. Here is an example:

@Entity
@Inheritance
@DiscriminatorColumn(name=""TRADE_TYPE"")
@Table(name=""TRADE"")
public abstract class Trade {
  @Id private long id;
  @Version private long version;
    // ...
}

The persistence provider performs optimistic locking by comparing the value of the @Version field in the entity instance with the VERSION column from the database. Initially the provider reads the entity from the database and has a record of the current version. Therefore, the provider knows that another concurrent operation has successfully updated the entity when the values are different. If there is a difference in value during the write phase, EntityManager will raise an OptimisticLockException.

Adding this annotation on an integer value allows the provider to make a faster check on an entity's version without having to check every single field or property for equivalence. The persistence provider updates the @Version field or property automatically. User code should not interfere with this arrangement.

Pessimistic locking

Sometimes there is a strong business requirement for strict locking of database rows. JPA has support for pessimistic locking. An entity can be locked with a call to the EntityManager.lock(), refresh(), or find() methods. There are different types of locks available through the enumeration LockModeType including the default optimistic. The enumerations are: NONE, OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT, PESSIMISTIC_FORCE_INCREMENT, PESSIMISTIC_READ, PESSIMISTIC_WRITE, READ, WRITE, and OPTIMISTIC_FORCE_INCREMENT.

The underlying database itself must support pessimistic locking. In order to achieve pessimistic locking, the JPA providers take advantage of the database server features, such as database row locks and sometimes extended native SQL language statements: SELECT … FOR UPDATE.

Each of the LockModeType enumerations has a trade-off. It is interesting that there are two types of pessimistic modes: reading and writing. Locking an entity with a pessimistic query could lead to performance bottlenecks as it prevents other concurrency operations from reading the particular row from the database.

Here is an example of a pessimistic write operation for a trade confirmation operation:

@Stateless
public class TradeConfirmService {
  //...
  void confirmTrade( String tradeIdRef, String ref ) {
    Query query = entityManager.createNamedQuery(
        ""Trade.findTradeByIdRef"")
            .setParameter(""id"", tradeIdRef );
    List<Trade> trades = query.getResultList();
    Trade trade = trades.get(0);
    em.refresh( trade, PESSIMISTIC_WRITE );
    trade.setConfirmFlag(true);
    trade.setTraderConfirmRef(ref);
    em.flush(); // optional
  }
}

A trade is retrieved optimistically using a named query. It is pessimistically locked for the write operation with the refresh() call on the entity manager. New values are set on the trade instance and EntityManager is flushed to update the database.