3.4. Stateful Session Beans in EJB 3.0

3.4. Stateful Session Beans in EJB 3.0

To cluster stateful session beans in EJB 3.0, you need to tag the bean implementation class with the @Cluster annotation, just as we did with the EJB 3.0 stateless session bean earlier. The @org.jboss.ejb3.annotation.cache.tree.CacheConfig annotation can also be applied to the bean to specify caching behavior. Below is the definition of the @CacheConfig annotation:

 
public @interface CacheConfig
{
String name() default "jboss.cache:service=EJB3SFSBClusteredCache";
int maxSize() default 10000;
long idleTimeoutSeconds() default 300;   
boolean replicationIsPassivation() default true;   
long removalTimeoutSeconds() default 0;
} 

Here is an example of a clustered EJB 3.0 stateful session bean implementation.

@Stateful
@Clustered
@CacheConfig(maxSize=5000,removalTimeoutSeconds=18000)
public class MyBean implements MySessionInt {
   
   private int state = 0;

   public void increment() {
      System.out.println("counter: " + (state++));
   }
}
            

As with stateless beans, the @Clustered annotation can also be omitted and the clustering configuration applied in jboss.xml; see the example above.

As with EJB 2.0 clustered SFSBs, JBoss provides a mechanism whereby a bean implementation can expose a method the container can invoke to check whether the bean's state is not dirty after a request and doesn't need to be replicated. With EJB3, the mechanism is a little more formal; instead of just exposing a method with a known signature, an EJB3 SFSB must implement the org.jboss.ejb3.cache.Optimized interface:

public interface Optimized {
boolean isModified();
}

JBoss Cache provides the session state replication service for EJB 3.0 stateful session beans. The related MBean service is defined in the ejb3-clustered-sfsbcache-service.xml file in the deploy directory. The contents of the file are as follows.

 
<server>
	<mbean code="org.jboss..cache.TreeCache"
	name="jboss.cache:service=EJB3SFSBClusteredCache">
	  
		<attribute name="ClusterName">
			${jboss.partition.name:DefaultPartition}-SFSBCache
			</attribute>
			<attribute name="IsolationLevel">REPEATABLE_READ</attribute>
			<attribute name="CacheMode">REPL_ASYNC</attribute> 
		  
			<!-- We want to activate/inactivate regions as beans are deployed --> 
			 <attribute name="UseRegionBasedMarshalling">true</attribute> 
			<!-- Must match the value of "useRegionBasedMarshalling" --> 
			<attribute name="InactiveOnStartup">true</attribute>
			  
			<attribute name="ClusterConfig">
			... ...
			</attribute> 
			  
			<!-- The max amount of time (in milliseconds) we wait until the 
			initial state (ie. the contents of the cache) are retrieved from 
			existing members.  --> 
			<attribute name="InitialStateRetrievalTimeout">17500</attribute>
			  
			<!--  Number of milliseconds to wait until all responses for a
				synchronous call have been received.
				-->
			<attribute name="SyncReplTimeout">17500</attribute>
			  
			<!--  Max number of milliseconds to wait for a lock acquisition -->
			<attribute name="LockAcquisitionTimeout">15000</attribute>
			  
			 <!--  Name of the eviction policy class. -->
			<attribute name="EvictionPolicyClass">
				org.jboss.cache.eviction.LRUPolicy
			</attribute>
			  
			<!--  Specific eviction policy configurations. This is LRU -->
			<attribute name="EvictionPolicyConfig">
			 <config>
				<attribute name="wakeUpIntervalSeconds">5</attribute>
				 <name>statefulClustered</name> 
				<!-- So default region would never timeout -->
				<region name="/_default_">
				<attribute name="maxNodes">0</attribute>
				 <attribute name="timeToIdleSeconds">0</attribute>
				</region>
			</config>
		</attribute> 
					  
	<!-- Store passivated sessions to the file system --> 
	 <attribute name="CacheLoaderConfiguration"> 
	<config> 
	  
	 <passivation>true</passivation> 
	<shared>false</shared> 
							  
	  <cacheloader> 
		 <class>org.jboss.cache.loader.FileCacheLoader</class> 
		<!-- Passivate to the server data dir --> 
		 <properties> 
			location=${jboss.server.data.dir}${/}sfsb 
		</properties> 
		<async>false</async> 
		<fetchPersistentState>true</fetchPersistentState> 
		<ignoreModifications>false</ignoreModifications> 
		</cacheloader> 
		  
			 </config> 
	   </attribute>
	</mbean>
</server>

The configuration attributes in this MBean are essentially the same as the attributes in the standard JBoss Cache TreeCache MBean discussed in Chapter 7, JBossCache and JGroups Services. Again, we omitted the JGroups configurations in the ClusterConfig attribute (see more in Section 7.1, “JGroups Configuration”). Two noteworthy items: