Stateful Session Bean State Management

In the following example, we create an AccountBean with two instance variables ‘name’ and ‘balance’. We show that the container assigns the same instance to the client on multiple invocations. The stateful session bean instance is associated with the client until the client session completes or times out.

  1. Create a business interface either Remote or Local
  2. package com.ibytecode.business;
    import javax.ejb.Remote;
    
    @Remote
    public interface Account {
    
    	void deposit(double amount);
    	String printAccountDetails();
    	public String getName();
    	public void setName(String name);
    	public double getBalance();
    	public void setBalance(double balance);
    }
  3. Create the bean implementation class.
  4. package com.ibytecode.businesslogic;
    
    import com.ibytecode.business.Account;
    import javax.ejb.Stateful;
    
    @Stateful
    public class AccountBean implements Account {
    	private String name;
    	private double balance;
    	
       	public AccountBean() {}
    
    	public void deposit(double amount) {
    		balance = balance + amount;		
    	}
    
    	public String printAccountDetails() {
    		return "Account [name=" + name + ", balance=" + balance + "]";
    	}
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public double getBalance() {
    		return balance;
    	}
    	public void setBalance(double balance) {
    		this.balance = balance;
    	}
    }
    
  5. Create the java application client.
  6. package com.ibytecode.client;
    
    import javax.naming.Context;
    import javax.naming.NamingException;
    
    import com.ibytecode.business.Account;
    import com.ibytecode.businesslogic.AccountBean;
    
    public class AccountBeanClient implements Runnable{
    
    	public static void main(String[] args) {
    		AccountBeanClient obj1 = new AccountBeanClient();
    		for(int i = 0 ; i < 10; i++) {
    			Thread t1 = new Thread(obj1, "T" + i);
    			t1.start();
    		}
    	}
    
    	@Override
    	public void run() {
    		Account bean = doLookup();
    
    		// 1. Setting name and balance
    		bean.setName(Thread.currentThread().getName());
    		bean.setBalance(Math.ceil(Math.random() * 10000));
    		
    		// 2. Reading the state of the bean for the first time
    		System.out.println(Thread.currentThread().getName() + 
    				" -> Reading Name : " + bean.getName());
    		System.out.println(Thread.currentThread().getName() + 
    				" -> Reading Balance : " + bean.getBalance());
    		System.out.println(Thread.currentThread().getName() + 
    				" " + bean.printAccountDetails());
    	}
    
    	//JNDI Lookup differs based on different containers
    	private static Account doLookup() {
    		.........
    		//Refer example link for complete code
    	}
    }
    
  7. We create 10 threads (with names T0 – T9) which requests access to the bean and its operations.
  8. The container on each request from the same client assigns the same instance (until the session completes or times out) which can be seen in the below output.

    T3 -> Reading Name : T3
    T7 -> Reading Name : T7
    T9 -> Reading Name : T9
    T5 -> Reading Name : T5
    T3 -> Reading Balance : 2371.0
    T8 -> Reading Name : T8
    T0 -> Reading Name : T0
    T4 -> Reading Name : T4
    T7 -> Reading Balance : 9477.0
    T5 -> Reading Balance : 5811.0
    T9 -> Reading Balance : 5560.0
    T1 -> Reading Name : T1
    T3 Account [name=T3, balance=2371.0] T8 -> Reading Balance : 4286.0
    T2 -> Reading Name : T2
    T0 -> Reading Balance : 8484.0
    T4 -> Reading Balance : 9361.0
    T1 -> Reading Balance : 2308.0
    T9 Account [name=T9, balance=5560.0] T2 -> Reading Balance : 7886.0
    T4 Account [name=T4, balance=9361.0] T0 Account [name=T0, balance=8484.0] T1 Account [name=T1, balance=2308.0] T8 Account [name=T8, balance=4286.0] T5 Account [name=T5, balance=5811.0] T7 Account [name=T7, balance=9477.0] T6 -> Reading Name : T6
    T2 Account [name=T2, balance=7886.0] T6 -> Reading Balance : 2168.0
    T6 Account [name=T6, balance=2168.0]

  9. The thread T3 on operations getName(), getBalance() and printAccountDetails() gives same results as set operations because the same instance is assigned to the client by the container.

    T3 -> Reading Name : T3
    T3 -> Reading Balance : 2371.0
    T3 Account [name=T3, balance=2371.0]

Refer this link for complete code.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.