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.
- Create a business interface either Remote or Local
- Create the bean implementation class.
- Create the java application client.
- We create 10 threads (with names T0 – T9) which requests access to the bean and its operations.
- 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] - 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]
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); }
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; } }
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 } }
Refer this link for complete code.