Thursday, January 29, 2009

A variety of implementations is available that all differs a little bit from one another.

Ad. 1. DataSourceTransactionManagerThe simplest implementation available that is capable of managing transaction using a JDBC connection originating from a single DataSource. This transaction manager is capable of managing transactions in any environment as long as the setup uses a DataSource.

Application code that wants to manage transactions using this transaction manager need to obtains JDBC connections either through DataSourceUtils.getConnection() or by using one of Spring's other data-access utility classes, such as the JdbcTemplate. Obtaining a connection directly from the DataSource will prevent the transaction manager from kicking in.

Ad.2. HibernateTransactionManagerPlatformTransactionManager implementation for a single Hibernate SessionFactory. Binds a Hibernate Session from the specified factory to the thread, potentially allowing for one thread-bound Session per factory. SessionFactoryUtils and HibernateTemplate are aware of thread-bound Sessions and participate in such transactions automatically. Using either of those is required for Hibernate access code that needs to support this transaction handling mechanism.

Ad. 3. JdoTransactionManagerPlatformTransactionManager implementation for a single JDO PersistenceManagerFactory. Binds a JDO PersistenceManager from the specified factory to the thread, potentially allowing for one thread-bound PersistenceManager per factory. PersistenceManagerFactoryUtils and JdoTemplate are aware of thread-bound persistence managers and participate in such transactions automatically. Using either of those (or going through a TransactionAwarePersistenceManagerFactoryProxy is required for JDO access code supporting this transaction management mechanism.

Ad. 4. JmsTransactionManagerPlatformTransactionManager implementation for a single JMS ConnectionFactory. Binds a JMS Connection/Session pair from the specified ConnectionFactory to the thread, potentially allowing for one thread-bound Session per ConnectionFactory.

This local strategy is an alternative to executing JMS operations within JTA transactions. Its advantage is that it is able to work in any environment, for example a standalone application or a test suite, with any message broker as target. However, this strategy is not able to provide XA transactions, for example in order to share transactions between messaging and database access. A full JTA/XA setup is required for XA transactions, typically using Spring's JtaTransactionManager as strategy.

Ad. 5. JpaTransactionManagerPlatformTransactionManager implementation for a single JPA EntityManagerFactory. Binds a JPA EntityManager from the specified factory to the thread, potentially allowing for one thread-bound EntityManager per factory. SharedEntityManagerCreator and JpaTemplate are aware of thread-bound entity managers and participate in such transactions automatically. Using either is required for JPA access code supporting this transaction management mechanism.

This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.

Ad. 6. JtaTransactionManagerPlatformTransactionManager implementation for JTA, delegating to a backend JTA provider. This is typically used to delegate to a J2EE server's transaction coordinator, but may also be configured with a local JTA provider which is embedded within the application.

This transaction manager is appropriate for handling distributed transactions, i.e. transactions that span multiple resources, and for controlling transactions on application server resources (e.g. JDBC DataSources available in JNDI) in general. For a single JDBC DataSource, DataSourceTransactionManager is perfectly sufficient, and for accessing a single resource with Hibernate (including transactional cache), HibernateTransactionManager is appropriate, for example.

Uses OC4J's special begin(name) method to start a JTA transaction, in orderto make Spring-driven transactions visible in OC4J's transaction monitor. In case of Spring's declarative transactions, the exposed name will (by default) be the fully-qualified class name + "." + method name.

Ad. 8. TopLinkTransactionManagerPlatformTransactionManager implementation for a single TopLink SessionFactory. Binds a TopLink Session from the specified factory to the thread, potentially allowing for one thread-bound Session per factory. SessionFactoryUtils and TopLinkTemplate are aware of thread-bound Sessions and participate in such transactions automatically. Using either of those or going through Session.getActiveUnitOfWork() is required for TopLink access code supporting this transaction handling mechanism.

This transaction manager is appropriate for applications that use a single TopLink SessionFactory for transactional data access. JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure TopLink with an appropriate external transaction controller in order to make it participate in JTA transactions.

Uses WebLogic's special begin(name) method to start a JTA transaction, in order to make Spring-driven transactions visible in WebLogic's transaction monitor. In case of Spring's declarative transactions, the exposed name will (by default) be the fully-qualified class name + "." + method name.

EJB 3.0 takes away much of the pain associated with maintaining the Local and Remote interfaces for Session Beans. However, there are still some issues that you need to be aware of.By design, the EJB specification disallows the same Business interface to be marked as @Local as well as @Remote (this restriction has been added in a revision to the PFD). The reason for this is that remote interfaces have different semantics to local interfaces, and it is usually inappropriate for the same method to be exposed as a remote interface as well as local interface. The problems are two-fold:1. Remote interfaces must typically be designed to be coarse-grained.2. Remote interfaces do not support the pass-by-reference semantics of parameter passing as in local interfaces.Having separate Remote and Local interfaces forces designers to think about how the interfaces will be used and ensure that the design is optimised for the use case. It also reduces the chances of errors caused by incorrect semantics, such as clients relying upon ability to pass parameters by reference.A drawback to this approach is that it does not allow transparent redeployment of an EJB from a co-located environment to a distributed environment or vice-versa. While such re-deployment has its dangers, there are times when it can prove useful to have such a facility.Ideally, you should define your Session beans to have either remote or local interface. This will keep the design simple and allow you to implement Business Logic as POJOs.If you do want to endow the same Session Bean with both remote and local interfaces, then, I suggest that you use the following example as a model:public interface CustomerService { void createCustomer(District d, Customer c); void removeCustomer(Long id); List findByDistrict(District d); @Remote public interface IRemote extends CustomerService { } @Local public interface ILocal extends CustomerService { }}Note that the local and remote interfaces extend a common business interface. Also note that the local and remote interfaces are nested within the business interface. I like this model because it reduces the clutter, keeps related interfaces together, and eases understanding.

After trying out various IDEs for editing Java Server Faces (JSF) files, I have finally settled on Oracle's JDeveloper as the best tool for the purpose. I had assumed that JDeveloper would insist on using ADF, but found to my pleasant surprise that it also allows you to design standard JSF pages in a visual manner. Unlike Sun Java Studio Creator which creates its own backing bean class, JDeveloper gives you full control, and lets you decide whether you want all/some/none of your UI components to be in your backing bean

To setup an Oracle Datasource in Glassfish, follow these steps:1. Copy the Oracle JDBC drivers to /glassfish/domains/domain1/lib/ext directory. You may need to change the directory /glassfish/domains/domain1 to match your installation of Glassfish and the domain name.2. Start Glassfish.3. Login to the admin interface and create a JDBC Connection Pool.Delete all properties, and add following properties:user - set this to Oracle useridpassword - set this to Oracle passwordURL - set this to the URL, example jdbc:oracle:thin:@localhost:1521:xe.xa-driver-does-not-support-non-tx-operations - set this to true.Test the connection pool using ping.4. Create a JDBC DataSource using the Connection Pool.