Thursday, June 16, 2011

Declarative transaction support for your JPA data model

While playing around with new featured of 11.1.2.0.0 release, noticed an interesting one on data control side - declarative support for building Transactional Data Control for the business services built using JPAs. It looks cool ! There are a couple of points you may need to be aware of when you try this one.

1. Your should not keep 'Auto Commit' option 'true' for Java Service Facade if you need to defer the transaction commit. If this flag is ON, transaction will get committed as part of each service invocation from client.

2. ADF binding layer will never request the EntityManager to manage your entities at run time. So its your responsibility to associate your detached entities with PersistenceContext by calling EntityManager::persist(...) or EntityManager.merge(...) through generated wrapper method from the service facade.

Generating Transactional Data Control for your Java Service Facade

If you are new to EJB and never used ADF binding support to build UI for JPA entities, then please see this post first - Creating a Data Capture Form using EJB + JPA and ADF Binding. In this post I'm not covering the preliminary steps for generating JPA. Once you generate the JPA model, next step is to build service layer. This can be achieved by either using Java Services Facade or Session Bean. In this post I'm focusing on Java Service Facade. Please note if you build service facade built using stateful session bean also got similar support what we discuss here.

In 11.1.2.0.0 release, the wizard for building Java Service Facade is more intelligent than before ;) The detailed steps for building Transactional Data Control for your Java Service Facade is given below.

1. Right click the model project, from the context menu select -> New -> EJB. Then from the Items list select Java Service Facade. The IDE will display a Java Service Facade creation wizard for you. In the first step, you may need to select 'Application Managed' Transactional Option. You can keep the default options as is for the rest and finish the wizard.


2. Now select the generated JavaServiceFacade class, right click and select Create Data Control option. You may get a window as shown below. Select all three options.
and click OK. This action will modify your class to implement the selected interfaces and generate necessary code to support the contracts set by the interfaces.


API doc says,
TransactionalDataControl : This interface is to be implementated by DataControls that supports transaction.
UpdateableDataControl : This interface is to be implemented by DataControls that support an updateable or mutable business service.
ManagedDataControl: This interface is implemented by data controls that needs to have each request demarcated by beginRequest/endRequest pair, so that request level initialization and cleanup processing is possible

You may notice that the data control pallet in your JDeveloper displays Commit and Rollback operations for your transactional data control. Your data control is really smart now. If you have any bounded task flow using this data control, then you can rely on declarative transaction mechanism available with the task flows to commit your business data.


Download

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.0.0 (11g R2) + HR Schema]

A glance at the implementation

This example is built using JPA entities and the Java Service Facade implementing oracle.binding.TransactionalDataControl. The Departments entity holds a status flag(Enum) to keep track of the modification status. The view controller project contains a dept-task-flow comprising a view activity - dept.jsf . The dept view uses the JavaServiceFacade as data provider. The task flow's transaction is controlled declaratively. Please note that merging modified entities with PersistenceContext is done programmatically from the view.DeptBean::doSave() method.

How to run this sample?

Run main.jsf and click on 'Show Departments', this action will take you to dept-task-flow.
Edit few records and click on Save. The save action is mapped to task flow return. This action commits the EntityTransaction by leveraging declarative transaction management support provided by the bounded task flow.

3 comments:

Edwin Biemond said...

Hi,

great post, I was already wondering what the new EJB DC transaction option was.

So you don't need an Session Bean / JTA and can you still use a jdbc datasource?

Jobinesh said...

To avail data source we really don't need a session bean. However for a huge JavaEE based Enterprise application, SSB may fit well as it gets manged by the container and helps you to pass context between service calls declaratively

Anonymous said...

Hi,

Is it possible to use transactions based on Java Bean only (for example, there is a collection (private field in Bean) populated with web service (when fetching data occurs) that is not exposed directly and we do not desire to expose WS as DataControl). Reason for this would be to use this collection as binding for the table/form, where we can support editing like it was database originated record. Once control participates in a page flow, we can issue commit (that would do nothing) or rollback (that would issue compensating WS call to remove added rows or performed actions).

Any pointer to example is appreciated.

Thanks!