Summary: If you’re considering using Spring or Hibernate with IBM® WebSphere® Application Server, this article explains how to configure these frameworks for various scenarios with WebSphere Application Server. This article is not an exhaustive review of either framework, but a critical reference to help you successfully implement such scenarios. (Updated with new security information.) This content is part of the IBM
The Spring Framework, commonly referred to as Spring, is an open source project that aims to make the J2EE™ environment more accessible. Spring provides a framework for simple Java™ objects that enables them to make use of the J2EE container via wrapper classes and XML configuration. Spring’s objective is to deliver significant benefits to projects by increasing development productivity and runtime performance, while also improving test coverage and application quality.
Hibernate is an open source persistence and query framework that provides object-relational mapping of POJOs (Plain Old Java Objects) to relational database tables, as well as data query and retrieval capabilities.
While many organisations are interested in discovering what benefits they can obtain from using these frameworks, IBM wants customers who do use them to know that they can do so with WebSphere Application Server in a robust and reliable way. This article describes how these frameworks can be used with WebSphere Application Server, and explains best practices for a variety of use cases so that you can get started with Spring or Hibernate as quickly as possible.
Spring is generally described as a lightweight container environment, though it is probably
more proper to describe it as a framework for simplifying development. The Spring Framework was developed by Interface21, based on publications by Rod Johnson on the dependency injection design pattern. Spring can be used either in standalone applications or with application servers. Its main concept is the use of dependency injection and aspect-oriented programming to simplify and smooth the transitions from development to testing to production.
One of the most often used scenarios involving Spring is to configure and drive business logic using simple Java bean classes. The Spring documentation should provide enough information to build an application using Spring beans; there is nothing WebSphere-specific about this. The following sections describe some of the usage scenarios for using Spring on WebSphere Application Server. Spring applications that are developed following the advice in this article should execute within a WebSphere Application Server or WebSphere Application Server Network Deployment environment with no difficulties.
Except where explicitly stated, the information presented here pertains to Versions 6.0.2.x, 6.1.x, and 7.0.x of WebSphere Application Server on all platforms.
Presentation tier considerations
This section describes considerations relating to the use of Spring in the Web-based presentation tier.
* Web MVC frameworks
Spring’s Web MVC framework is an alternative to other frameworks that have been around for some time. Web MVC frameworks delivered, used, and supported directly by WebSphere Application Server include JavaServer Faces (JSF) and Struts. Spring documentation describes how to integrate Spring with these Web frameworks. Use of any of these MVC is supported by WebSphere Application Server, although IBM will only provide product support for the frameworks shipped with WebSphere Application Server.
* Portlet MVC framework
Spring also provides a Portlet MVC framework (which mirrors the Spring Web MVC framework) and runs in both the WebSphere Portal V6.0 and the WebSphere Application Server V6.1 portlet containers. (See Spring Portlet MVC for an example set of Spring portlets.) Running portlets in the WebSphere Application Server V6.1 portlet container requires that an additional Web application be created to define the layout and aggregation of the portlets. Information on how to use the portlet aggregator tag library can be found in the WebSphere Application Server Information Center and in the article Introducing the portlet container. Using JSF in combination with portlets is a common practice for rendering. For information on how Spring, Hibernate, JSF, and WebSphere Portal can be combined together, see Configuring Hibernate, Spring, Portlets, and OpenInSessionViewFilter with IBM WebSphere Portal.
Data access considerations
This section describes considerations relating to the configuration of Spring beans that access data within a transaction.
The Spring framework essentially wraps Spring beans with a container-management layer that, in a J2EE environment, delegates to the underlying J2EE runtime. Following are descriptions of how Spring beans should be configured so that the Spring Framework properly delegates to (and integrates with) the WebSphere Application Server runtime.
* Accessing data sources configured in WebSphere Application Server
WebSphere Application Server manages the resources used within the application server execution environment. Spring applications that want to access resources, such as JDBC data sources, should utilize WebSphere-managed resources. To do this:
1. During development, the WAR module should be configured with a resource reference. For example:
2. For EJB JAR files, the same resource-ref should be declared in each EJB that needs to access the data source.
3. A data source proxy bean would then be declared within the Spring application configuration, which references a WebSphere-managed resource provider:
Accessing the data source through this proxy bean will cause the data source to be looked up using the module’s configured references, and hence be properly managed by WebSphere Application Server. Note that the jndiName property value matches the pattern java:comp/env/ concatenated with the res-ref-name declared in the resource-ref.
Alternatively, from Spring 2.5 onwards, this can be done using the
4. The data source proxy bean may then be used by the Spring application as appropriate.
5. When the application is deployed to a WebSphere Application Server, a resource provider and resource data source must be configured in the normal fashion for use by the Spring application resource reference. The resource reference declared within the module’s deployment descriptor will be bound to the application server’s configured data source during deployment.
* Using JDBC native connections
Spring provides a mechanism for accessing native connections when various JDBC operations require interacting with the native JDBC resource. The Spring JdbcTemplate classes utilize this capability when a NativeJdbcExtractor class has been set on the JdbcTemplate class. Once a NativeJdbcExtractor class has been set, Spring always drills down to the native JDBC connection when used with WebSphere Application Server. This bypasses the following WebSphere quality of service functionality and benefits:
o Connection handle tracking and reassociation
o Connection sharing
o Involvement in transactions
o Connection pool management.
Another problem with this is the WebSphereNativeJdbcExtractor class depends on internal WebSphere adapter classes. These internal classes may differ by WebSphere Application Server version and may change in the future, thereby breaking applications that depend on this functionality.
Use of NativeJdbcExtractor class implementations (for example, WebSphereNativeJdbcExtractor) are not supported on WebSphere Application Server and you should avoid scenarios that require it. The alternative is to use the WebSphere Application Server WSCallHelper class to access non-standard vendor extensions for data sources.
* Using transactions with Spring
WebSphere Application Server provides a robust and scalable environment for transaction processing and for managing connections to resource providers. Connections to JDBC, JMS, and Java Connector resource adapters are managed by WebSphere Application Server regardless of whether or not a global transaction is being used; even in the absence of a global transaction there is always a runtime context within which all resource-provider connections are accessed. WebSphere Application Server refers to this runtime context as a local transaction containment (LTC) scope; there is always an LTC in the absence of a global transaction, and resource access is always managed by the runtime in the presence of either of a global transaction or an LTC. To ensure the integrity of transaction context management (and hence the proper management of transactional resources) WebSphere Application Server does not expose the javax.transaction.TransactionManager interface to applications or application frameworks deployed into WebSphere Application Server.
There are a number of ways to drive resource updates under transactional control in Spring, including both programmatic and declarative forms. The declarative forms have both Java annotation and XML descriptor forms. If you use Spring 2.5 with WebSphere Application Server V18.104.22.168 or V22.214.171.124 or later, you can take advantage of full support for Spring’s declarative transaction model. Spring 2.5 has a new PlatformTransactionManager class for WebSphere Application Server, called WebSphereUowTransactionManager, which takes advantage of WebSphere Application Server’s supported UOWManager interface for transaction context management. Managing transaction demarcation through WebSphere Application Server’s UOWManager class ensures that an appropriate global transaction or LTC context is always available when accessing a resource provider. However, earlier versions of Spring used internal WebSphere interfaces that compromised the ability of the Web and EJB containers to manage resources and are unsupported for application use. This could leave the container in an unknown state, possibly causing data corruption.
Declarative transaction demarcation in Spring 2.5 or later are supported in WebSphere Application Server using the following declaration for the WebSphere transaction support:
A Spring bean referencing this declaration would then use standard Spring dependency injection to use the transaction support, for example:
Alternatively, from Spring 2.5 onwards, Spring’s AspectJ support can be utilised. In the following example,
Another alternative mechanism for declaring transaction settings is to use the Spring annotation-based transaction support. This requires the use of Java 5+, and therefore cannot be used with WebSphere Application Server V6.0.2.x.
Add the following to the Spring.xml configuration:
Any methods that require transactional attributes should then be marked with the @Transactional annotation:
@Transactional(readOnly = true)
public String getUserName()
Be aware that the @Transactional annotation can only be used to annotate public methods.
The WebSphereUowTransactionManager supports each of the Spring transaction attributes:
For earlier versions of Spring that do not provide org.springframework.transaction.jta.WebSphereUowTransactionManager, and for versions of WebSphere Application Server prior to V126.96.36.199 or V188.8.131.52 that do not provide com.ibm.wsspi.uow.UOWManager, transaction support in WebSphere Application Server is available via this Spring configuration:
This configuration supports a restricted set of transaction attributes that does not include PROPAGATION_NOT_SUPPORTED and PROPAGATION_REQUIRES_NEW. The Spring class org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean, which also claims to provide PROPAGATION_NOT_SUPPORTED and PROPAGATION_REQUIRES_NEW capabilities, uses unsupported internal WebSphere Application Server interfaces and should not be used with WebSphere Application Server.
* Using Spring JMS
Just as with accessing JDBC data sources, Spring applications intended to access JMS destinations must ensure they use WebSphere-managed JMS resource providers. The same pattern of using a Spring JndiObjectFactoryBean as a proxy for a ConnectionFactory will ensure that JMS resources are properly managed.
For JMS message sending or synchronous JMS message receipt, JMSTemplates can be used. This includes the use of Spring’s dynamic destination resolution functionality both via JNDI and true dynamic resolution.
The following example shows the configuration of a resource reference for a ConnectionFactory. This reference is mapped during application deployment to point to a configured, managed ConnectionFactory stored in the application server’s JNDI namespace. The ConnectionFactory is required to perform messaging and should be injected into the Spring JMSTemplate.
There is now a defined JNDI name for your ConnectionFactory within the application that can be looked up and injected into the JMSTemplate:
At run time, the JMSTemplate can locate destinations based on either their JNDI name (as configured in an application resource reference) or through “dynamic resolution,” based on the administrative name of the destination configured in WebSphere Application Server; for example, for the JMS myQueue queue, bound to a JNDI reference of jms/myQueue:
As an alternative to J2EE message-driven beans (MDBs), Spring provides a message-driven POJO model for processing inbound JMS messages asynchronously. Only a DefaultMessageListenerContainer class will manage messages from the JMS queue to the configured POJO that must be a javax.jms.MessageListener implementation.
In a WebSphere Application Server environment, you must also specify a WorkManagerTaskExecutor class, which means the DefaultMessageListenerContainer class will delegate to a server-managed thread pool. The DefaultMessageListenerContainer should also be configured with the server’s transaction management via the WebSphereUowTransactionManager, as described above.
While this message-driven POJO model can be used, it is recommended that J2EE message-driven beans (MDBs) be used directly in WebSphere Application Server configurations that require workload management and/or high availability. Be aware that no other Spring JMS MessageListenerContainer types are supported, as they can start unmanaged threads and might also use JMS APIs that should not be called by applications in a Java EE environment.
* Using JPA with Spring
The EJB 3.0 specification defines the Java Persistence API (JPA) as the means for providing portable persistent Java entities. WebSphere Application Server V7 and the WebSphere Application Server V6.1 EJB 3 feature pack both provide implementations of EJB 3 and JPA; it is also possible to use the Apache OpenJPA implementation of JPA with WebSphere Application Server V6.1 (see Resources). When Spring is used in conjunction with a JPA implementation, you should use JPA directly rather than using Spring’s JPA helper classes (in the org.springframework.orm.jpa package).
WebSphere Application Server V6.1 and later supports JPA application-managed entity managers, which might have a transaction type of either JTA or resource-local. JTA entity manager uses the application server’s underlying JTA transaction support, for which transaction demarcation can be defined using either standard J2EE techniques or Spring’s declarative transaction model, as described above.
A data access object (DAO) that uses JPA is packaged with a persistence.xml that defines persistence context for the JPA EntityManager used by the application. For example, a persistence.xml for a JTA entity manager that uses the data source with a JNDI name “java:comp/env/jdbc/springdb” can be set up like this:
By setting the openjpa.TransactionMode and openjpa.ConnectionFactoryMode properties to “managed,” the JPA entity manager delegates management of transactions and connections to WebSphere Application Server. The DAO may use Spring’s declarative transaction demarcation as described above.
Annotation style injection of a JPA EntityManager is also possible. This is identical to standard JPA:
private EntityManager em;
You need this XML code to turn on EntityManager injection in the Spring XML configuration:
Spring will create an EntityManager from any EntityManagerFactory defined in this XML file. If more than one exists, then it will fail. Use one (and only one) of these ways to create an EntityManagerFactory:
o Using Spring’s basic configuration
o Using Spring’s advanced configuration
Of course, the benefits of annotations and JPA are also available by using the pure EJB 3 support in WebSphere Application Server V7 and the WebSphere Application Server V6.1 EJB 3 Feature Pack. In either case, you can create an EntityManagerFactory using the JPA API, as shown below. This approach is not recommended for a non-EJB 3 environment, because any EntityManagers created might not be properly managed. However, when you do have an EJB 3 environment, you can use this approach to separate your Spring and JPA configurations.
The jta.UserTransaction property configures the factory class to obtain an instance of a UserTransaction object instance from the WebSphere container.
The hibernate.transaction.manager_lookup_class property is supported on the WebSphere platform by WebSphere Application Server V6.x and later, and on WebSphere Business Integration Server Foundation V5.1 and later. This property configures Hibernate to use the ExtendedJTATransaction interface, which was introduced in WebSphere Business Integration Server Foundation V5.1 and WebSphere Application Server V6.0. The WebSphere ExtendedJTATransaction interface establishes a pattern that is formalized in Java EE 5 via the JTA 1.1 specification.
* Unsupported transaction configurations
The Hibernate documentation describes transaction strategy configurations for running on WebSphere Application Server Versions 4 and 5 products; however, these configurations use internal WebSphere interfaces and are not supported on those earlier versions. The only supported transaction configuration of Hibernate is described above, which means, as stated earlier, Hibernate usage is only supported on WebSphere Business Integration Server Foundation V5.1 and on WebSphere Application Server Version 6.x and later.
* Hibernate’s usage patterns within a WebSphere Application Server environment
Hibernate’s session-per-request and long conversation patterns are both available when using Hibernate with WebSphere Application Server. Customers must choose which is appropriate for their application, though it is our opinion that session-per-request offers better scalability.
o Multiple isolation levels
Sharable connections provide a performance improvement in WebSphere Application Server by enabling multiple resource users to share existing connections. However, if sharable connections and multiple isolation levels are both necessary, then define a separate resource-ref and Hibernate session-factory for each connection configuration. It is not possible to change the isolation level of a shared connection. Therefore, it is also not possible to use the hibernate.connection.isolation property to set the isolation level on a sharable connection. See Sharing connections in WebSphere Application Server V5 for more information on policies and constraints on connection sharing. (Although this article generally pertains to all shared connection use on WebSphere Application Server V5, the connection sharing advice still follows for Hibernate running on V6.x.)
o Web applications
Hibernate long conversation sessions can be used and stored in HttpSession objects; however, a Hibernate session holds active instances and, therefore, storing it in an HttpSession may not be a scalable pattern since sessions may need to be serialized or replicated to additional cluster members. It is better to use HttpSession to store disconnected objects (as long as they are small, meaning 10KB to 50KB) and re-associate them with a new Hibernate session when an update is needed. This is because HttpSession is best used for bookmarking and not caching. A discussion on how to minimize memory use in HttpSession is contained in Improving HttpSession Performance with Smart Serialization. Instead of using HttpSession as a cache, consider using a WebSphere data caching technology like ObjectGrid or DistributedObjectCache, as described in the next section.
For best practices on high performing and scalable applications, the book Performance Analysis for Java Websites is strongly recommended.
At the time of publication, the behavior of Hibernate’s cluster aware caches in conjunction with WebSphere Application Server has not been determined; therefore, it is not yet determined whether or not their use is supported and we will not discuss them further. As a result, customers requiring a distributed cache should consider creating a class that implements org.hibernate.cache.CacheProvider using the property hibernate.cache.provider_class, which employs one of the two distributed cache implementations in WebSphere.
* Integrating a second-level cache
A Hibernate session represents a scoping for a unit of work. The Session interface manages persistence during the lifecycle of a Hibernate session. Generally, it does this by maintaining awareness or state of the mapped entity class instances it is responsible for by keeping a first-level cache of instances, valid for a single thread. The cache goes away when the unit of work (session) is completed. A second-level cache also can be configured to be shared among all sessions of the SessionFactory, including across a cluster. Be aware that caching in Hibernate raises issues that will need to be addressed. First, no effort is made to ensure the cache is consistent, either with external changes to the database or across a cluster (unless using a cluster aware cache). Second, other layers (such as the database) may already cache, minimizing the value of a Hibernate cache. These issues must be carefully considered in the application design, but they are beyond the scope of this article.
Hibernate comes with several pre-configured caches. You can find information on them in the Hibernate Cache documentation pages. For read-only data, one of the in-memory caches might be enough. However, when the application is clustered and a cluster aware cache is needed, the local read-only caches are not enough. If a distributed cache is desired, we recommend using one of the WebSphere-provided distributed cache implementations. These can be used as a second level cache with Hibernate:
o The DistributedMap/DistributedObjectCache interfaces provide distributed cache support the WebSphere v6.x product family. See Using the DistributedMap and DistributedObjectCache interfaces for the dynamic cache for more information.
o ObjectGrid, available as part of the WebSphere Extended Deployment product, provides extensible object caching support. See ObjectGrid for more information.
* Using Hibernate in WebSphere Enterprise Service Bus and WebSphere Process Server
WebSphere Process Server and WebSphere Enterprise Service Bus (ESB) rely on the Service Component Architecture (SCA) and Service Data Objects (SDO) as an assembly and programming model for SOA. (See Resources to learn more about SCA and SDO.) SCA components are not Java EE components, so they do not have resource references, but rely instead on services and adapters to connect to systems. Resource references cannot be used when building Java SCA components; therefore, Hibernate cannot be used directly by an SCA component.
In this case, Hibernate persistence should be hidden behind some kind of facade. There are two alternatives:
o A local EJB session facade is created to wrap Hibernate persistence. The session facade provides adapter logic to map Hibernate entity POJOs to Service Data Objects and back. An integration developer can then use an EJB import to invoke the session facade, and invoke it in a tightly coupled fashion with corresponding Qualities of Service (QoS).
o An EJB Web service session facade is created to wrap Hibernate persistence. An integration developer can then use a Web service import to invoke the Web service for persistence. This gets around having to build POJO to SDO converters, since at the current time SCA only uses SDO for data types. Figure 1 illustrates a business process using both patterns, though the details of the process are beyond the scope of this article.
Figure 1. Sample business process
Figure 1. Sample business process
* Hibernate JPA API on WebSphere Application Server V6.1
Hibernate’s JPA support provides for JPA standard persistence and is a good alternative to the proprietary Hibernate APIs. Hibernate’s JPA implementation requires a Java SE 5 based runtime, and therefore only runs on WebSphere Application Server V6.1 or later. At the time of publication, Hibernate’s JPA support does not run on WebSphere System z or iSeries platforms. The Hibernate documentation describes how to package and deploy applications using Hibernate’s JPA implementation.
* Non-interoperable / Non-portable function
Section 184.108.40.206 in the JPA specification describes a scenario that is likely to cause interoperability and potential portability problems. This has to do with the combination of the use of lazy loading (that is, @Basic(fetch=LAZY)) and detached objects. When merging a detached object back into a session, JPA will examine the object and update the data store with any changed values. However, data objects are simple POJOs. If part of the POJO state wasn’t loaded when it was detached, it can appear to be changed when it is merged back in. To get this to work correctly, vendors must implement serialization techniques specific to their runtime. This is not interoperable and the semantics may not be portable either.
Back to top
Product and customer technical support
An area of reasonable concern for users is support of projects using open source and the impact of that usage upon a vendor’s support for its licensed products. IBM recognizes that some customers may desire to use non-IBM frameworks in conjunction with IBM WebSphere Application Server and is providing information to customers that may promote the creation of the most reliable operating environment for IBM WebSphere Application Server. IBM considers open source code and application frameworks installed by customers, either bundled as part of the application or as shared libraries, to be part of application code. By carefully utilizing this information when using open source projects, customers may use IBM products with a higher degree of confidence that they may have continued access to IBM product and technical support. If a problem is encountered when using these frameworks with WebSphere products, IBM will make reasonable efforts to ensure the problem does not lie with the WebSphere product.
It is expected that customers may safely use frameworks such as Spring and Hibernate on IBM products by observing the suggestions of this article and understanding a few key points:
* Customers must ensure that they only use those frameworks in ways that are allowed by WebSphere Application Server. In particular, this means that frameworks should not be used when they use internal product interfaces — unfortunately many open source frameworks do this when not configured carefully. Customers should avoid scenarios clearly documented as things to avoid on WebSphere.
* For open source frameworks, customers should ensure they understand and have access to matching source code and binaries for the framework they are using with WebSphere Application Server.
* Customers are encouraged to obtain corrective service for the frameworks from the open source community or from partners working with the open source community.
For more details on IBM support and policy please refer to the IBM Support Handbook and WebSphere Application Server Support Statement.
Although following the suggested practices of this article will help you enhance your experience when using WebSphere Application Servers in an open source environment, it is not an all inclusive list of ways in which an open source component may impact WebSphere Application Server operation or the operation of other components. Users of open source code are urged to review the specifications of all components to avoid licensing, support, and technical issues.
Throughout this article, the terms “support” or “supported” indicates that the usage being described uses only IBM documented functionality. The authors have done their best to provide advice on how to configure and use these frameworks to ensure that their usage is consistent with documented product behavior, but this article is neither an endorsement nor a statement of support for Spring or Hibernate.