EJB factories and data classes
EJB factories and data class access beans typify the new access bean design found in the workbench.
This topic includes the following sections:
- Instantiating enterprise beans using EJB factories
- Setting the context factory and provider URL using EJB factories
- Cache operations using data classes
- Exception handling
Where appropriate, comparisons are made between EJB factories and data classes and Java bean wrappers and copy helpers that still employ the original design.
Instantiating enterprise beans using EJB factories
To explain how to use EJB factories to instantiate enterprise beans, assume that you have an existing entity bean named MyEJB. When MyEJBAccessBean is created, the default constructor is mapped to findByPrimaryKey(MyEJBKey). MyEJBKey has a single String field named field lastName.
In the original access bean design, you could use an access bean instance in the following way:
MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to findByPrimaryKey(MyEJBKey); ab.setInitKey_lastName = "stokes"; int i = ab.getAnInt(); // <- findByPrimaryKey(MyEJBKey) occurs here ...In the new access bean design, you can write the code in exactly the same way:
MyEJBFactory factory = new MyEJBFactory(); MyEJB myEjb = factory.findByPrimaryKey(new MyEJBKey("stokes")); int i = myEjb.getAnInt(); ...Or alternatively, you can write the code this way:
MyEJBFactory factory = new MyEJBFactory(); MyEJBKey key = new MyEJBKey("stokes"); MyEJB myEjb = factory.findByPrimaryKey(key); int i = myEjb.getAnInt(); ...In the original design, if you wanted to use a home interface method other than the one mapped to the no-arg constructor, then you might write the following code:
MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- create occurs here ab.setAnInt(5); ...In the new design, you would write the following code instead:
MyEJBFactory factory = new MyEJBFactory(); MyEJB myEjb = factory.create("stokes"); myEjb.setAnInt(5); ...Or, you could code it as follows:
MyEJB myEjb = new MyEJBFactory.create("stokes"); myEjb.setAnInt(5); ...If MyAccessBean used create(String) as the default home interface method, in the original design, you could construct an access bean instance this way:
MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to create(String); ab.setInit_argKey = "stokes"; int i = ab.getAnInt(); // <- create(String) occurs here ...Under the new design, you would use the following code:
MyEJBFactory factory = new MyEJBFactory(); MyEJB myEjb = factory.create("stokes"); int i = myEjb.getAnInt(); ...
Setting the context factory and provider URL using EJB factories
Assume that you need to refer to a naming context other than the one referenced by the current System property settings. If you have mapped the no-arg constructor to findByPrimaryKey(), then in the original design, you would use the following code:
MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to findByPrimaryKey(); ab.setInit_NameServiceTypeName("com.ibm...CNInitialContextFactory"); ab.setInit_NameServiceURLName("IIOP://9.21.35.100:900"); ab.setInitKey_lastName = "stokes"; int i = ab.getAnInt(); // <- findByPrimaryKey() occurs here ...In the new design, the same code can be written almost exactly the same way:MyEJBFactory factory = new MyEJBFactory(); factory.setInitialContextFactoryName("com.ibm...CNInitialContextFactory"); factory.setInitialNameServiceProviderURL("IIOP://9.21.35.100:900"); MyEJB myEjb = factory.findByPrimaryKey(new MyEJBKey("stokes")); int i = myEjb.getAnInt(); ...However, if you wanted to use a home interface method other than the one mapped to the default constructor (in this case findByPrimaryKey), then in the original design, you would not be able to use the following code:MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- create() occurs here // The following two lines have no effect, because the home is already acquired ab.setInit_NameServiceTypeName("com.ibm...CNInitialContextFactory"); ab.setInit_NameServiceURLName("IIOP://9.21.35.100:900"); int i = ab.getAnInt(); ...You would need to use the following code instead://The following two lines call static setters on the AbstractAccessBean class MyEJBAccessBean.setInit_GlobalNameServiceTypeName("com.ibm...CNInitialContextFactory"); MyEJBAccessBean.setInit_GlobalNameServiceURLName("IIOP://9.21.35.100:900"); MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- create() occurs here int i = ab.getAnInt(); ...However, this code is not thread safe. If the thread is interrupted immediately before its constructor call and another thread sets these global values to something else, then the access bean will note reference the name service that you have set. In the new design, you would use the following code:
MyEJBFactory factory = new MyEJBFactory(); factory.setInitialContextFactoryName("com.ibm...WsnInitialContextFactory"); factory.setInitialNameServiceProviderURL("IIOP://9.21.35.100:900"); MyEJB myEjb = factory.create("stokes"); int i = myEjb.getAnInt(); ...
Cache operations using data classes
If you are using a copy helper access bean to set several properties, then you might use the following code:
MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- maps to find(String) ab.setAnInt(5); ab.setAString("xxx"); ... ab.commitCopyHelper();In the new design, the cacheable properties would be stored in a separate object; for instance, MyEJBData. The code written for the copy helper would now be written as follows:
MyEJBData data = new MyEJBData(); data.setAnInt(5); data.setAString("xxx"); ... MyEJB myEjb = new MyEJBFactory().find("stokes"); myEjb.setMyEJBData(data);If you're using a copy helper access bean to get several properties, you might write something that resembled the following code:
MyEJBAccessBean ab = new MyEJBAccessBean("stokes"); // <- maps to find(String) int i = ab.getAnInt(); String s = ab.getAString(); ...Under the new design, the code would be written as follows:
MyEJB myEjb = new MyEJBFactory().find("stokes"); MyEJBData data = myEjb.getMyEJBData(); int i = data.getAnInt(); String s = data.getAString(); ...
Exception handling
In the original design, if you created MyEJBAccessBean with the default constructor mapped to findByPrimaryKey, then the client code might resemble the following fragment:
MyEJBAccessBean ab = new MyEJBAccessBean(); // maps to findByPrimaryKey(MyEJBKey); ab.setInitKey_lastName = "stokes"; try { int i = ab.getAnInt(); // <- findByPrimaryKey(MyEJBKey) occurs here ... } catch (NamingException nameExc) { ... } catch (FinderException finderExc) { ... } catch (CreateException createExc) { ... } catch (RemoteException remoteExc) { ... } // endtryIn the new design, the same code would be written as follows:
MyEJBFactory factory = new MyEJBFactory(); try { MyEJB myEjb = factory.findByPrimaryKey(new MyEJBKey("stokes")); int i = myEjb.getAnInt(); ... } catch (FinderException finderExc) { ... } catch (RemoteException remoteExc) { ... } // endtry
Parent topic
EJB access beans and client applications