Sunday, July 25, 2010

EntityManager vs EntityManagerFactory vs PersistenceContext

Clear understanding of Persistence unit, EntityManager, EntityManagerFactory and PersistenceContext are very impotent to work with JPA.
Persistence unit: Set of entity types(classes) that are grouped under a name.
Persistence context: A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle is managed by a particular entity manager. The scope of this context can either be the transaction, or an extended unit of work.
EntityManagerFactory: An entity manager factory provides entity manager instances, all instances are configured to connect to the same database. You can prepare several entity manager factories to access several data stores.
EntityManager provides API to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities.
An Entity Manager whose lifecycle is managed by the container is Container-managed entity manager.
An Entity Manager whose lifecycle is managed by the application is Application-managed entity manager.
Entity manager involved in a JTA transaction is JTA entity manager, generally its also container-managed entity manager.
Entity manager using a resource transaction (not a JTA transaction) is
Resource-local entity manager. Generally its Application-managed entty manager.

The most common and widely used entity manager in a Java EE environment is the container-managed entity manager. In this mode, the container is responsible for the opening and closing of the entity manager (this is transparent to the application). . A container-managed entity manager is obtained in an application through dependency injection or through JNDI lookup, A container-managed entity manger requires the use of a JTA transaction.

An application-managed entity manager allows you to control the entity manager in application code. This entity manager is retrieved through the EntityManagerFactory API. An application managed entity manager can be either involved in the current JTA transaction (using EntityManager.joinTransaction) , or the transaction may be controlled through the EntityTransaction API (a resource-local entity manager). The resource-local entity manager transaction maps to a direct resource transaction (i. e. JDBC transaction). The entity manager type (JTA or resource-local) is defined at configuration time, when setting up the entity manager factory.

Persistence context scope and Propagation
Persistence context scope can be bounded to a transaction or can be bounded to several transactions(extended transaction scope).

The most common case is to bind the persistence context scope to the current transaction scope. This is only doable when JTA transactions are used. The persistence context is associated with the JTA transaction life cycle. When an entity manager is invoked, the persistence context is also opened, if there is no persistence context associated with the current JTA transaction. Otherwise, the associated persistence context is used. The persistence context ends when the JTA transaction completes.

You can also use an extended persistence context. This can be combined with stateful session beans, if you use a container-managed entity manager: the persistence context is created when an entity manager is retrieved from dependency injection or JNDI lookup , and is kept until the container closes it after the completion of the Remove stateful session bean method. This is a perfect mechanism for implementing a "long" unit of work pattern.

A resource-local entity manager or an entity manager created with EntityManagerFactory.createEntityManager() (application-managed) has a one-to-one relationship with a persistence context and is always (in J2Se mode) extended persistence context.

Friday, July 16, 2010

Finding top N rows

oracle supports specifying order by clause in select statement.
Suppose we what get top n rows by a specific value.

table Run(startTime, ID, priority). To get top N priority items

SELECT p,
startTime, ID
FROM (
SELECT row_number() OVER (ORDER BY priority DESC) p,
startTime, ID
FROM Run
WHERE r > N;