A read-only bean is an EJB 2.1 entity bean that is never modified by an EJB client. The data that a read-only bean represents can be updated externally by other enterprise beans, or by other means, such as direct database updates.
Read-only beans are specific to the Enterprise Server and are not part of the Enterprise JavaBeans Specification, v2.1. Use of this feature for an EJB 2.1 bean results in a non-portable application.
To make an EJB 3.0 entity bean read-only, use @Column annotations to mark its columns insertable=false and updatable=false.
Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. The following topics are addressed in this section:
Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. For example, a read-only bean can be used to represent a stock quote for a particular company, which is updated externally. In such a case, using a regular entity bean might incur the burden of calling ejbStore, which can be avoided by using a read-only bean.
Read-only beans have the following characteristics:
Only entity beans can be read-only beans.
Either bean-managed persistence (BMP) or container-managed persistence (CMP) is allowed. If CMP is used, do not create the database schema during deployment. Instead, work with your database administrator to populate the data into the tables. See Chapter 10, Using Container-Managed Persistence.
Only container-managed transactions are allowed; read-only beans cannot start their own transactions.
Read-only beans don’t update any bean state.
ejbStore is never called by the container.
ejbLoad is called only when a transactional method is called or when the bean is initially created (in the cache), or at regular intervals controlled by the bean’s refresh-period-in-seconds element in the sun-ejb-jar.xml file.
The home interface can have any number of find methods. The return type of the find methods must be the primary key for the same bean type (or a collection of primary keys).
If the data that the bean represents can change, then refresh-period-in-seconds must be set to refresh the beans at regular intervals. ejbLoad is called at this regular interval.
A read-only bean comes into existence using the appropriate find methods.
Read-only beans are cached and have the same cache properties as entity beans. When a read-only bean is selected as a victim to make room in the cache, ejbPassivate is called and the bean is returned to the free pool. When in the free pool, the bean has no identity and is used only to serve any finder requests.
Read-only beans are bound to the naming service like regular read-write entity beans, and clients can look up read-only beans the same way read-write entity beans are looked up.
For best results, follow these guidelines when developing read-only beans:
Avoid having any create or remove methods in the home interface.
Use any of the valid EJB 2.1 transaction attributes for the trans-attribute element.
The reason for having TX_SUPPORTED is to allow reading uncommitted data in the same transaction. Also, the transaction attributes can be used to force ejbLoad.
There are several ways of refreshing read-only beans as addressed in the following sections:
Invoking any transactional method invokes ejbLoad.
Use the refresh-period-in-seconds element in the sun-ejb-jar.xml file to refresh a read-only bean periodically.
If the value specified in refresh-period-in-seconds is zero or not specified, which is the default, the bean is never refreshed (unless a transactional method is accessed).
If the value is greater than zero, the bean is refreshed at the rate specified.
This is the only way to refresh the bean state if the data can be modified external to the Enterprise Server.
By default, a single timer is used for all instances of a read-only bean. When that timer fires, all bean instances are marked as expired and are refreshed from the database the next time they are used.
Use the -Dcom.sun.ejb.containers.readonly.relative.refresh.mode=true flag to refresh each bean instance independently upon access if its refresh period has expired. The default is false. Note that each instance still has the same refresh period. This additional level of granularity can improve the performance of read-only beans that do not need to be refreshed at the same time.
To set this flag, use the asadmin create-jvm-options command. For example:
asadmin create-jvm-options --user adminuser -Dcom.sun.ejb.containers.readonly.relative.refresh.mode=true |
Typically, beans that update any data that is cached by read-only beans need to notify the read-only beans to refresh their state. Use ReadOnlyBeanNotifier to force the refresh of read-only beans.
To do this, invoke the following methods on the ReadOnlyBeanNotifier bean:
public interface ReadOnlyBeanNotifier extends java.rmi.Remote { refresh(Object PrimaryKey) throws RemoteException; }
The implementation of the ReadOnlyBeanNotifier interface is provided by the container. The bean looks up ReadOnlyBeanNotifier using a fragment of code such as the following example:
com.sun.appserv.ejb.ReadOnlyBeanHelper helper = new com.sun.appserv.ejb.ReadOnlyBeanHelper(); com.sun.appserv.ejb.ReadOnlyBeanNotifier notifier = helper.getReadOnlyBeanNotifier("java:comp/env/ejb/ReadOnlyCustomer"); notifier.refresh(PrimaryKey);
For a local read-only bean notifier, the lookup has this modification:
helper.getReadOnlyBeanLocalNotifier("java:comp/env/ejb/LocalReadOnlyCustomer");
Beans that update any data that is cached by read-only beans need to call the refresh methods. The next (non-transactional) call to the read-only bean invokes ejbLoad.
For Javadoc tool pages relevant to read-only beans, go to http://glassfish.dev.java.net/nonav/javaee5/api/index.html and click on the com.sun.appserv.ejb package.
Read-only beans are deployed in the same manner as other entity beans. However, in the entry for the bean in the sun-ejb-jar.xml file, the is-read-only-bean element must be set to true. That is:
<is-read-only-bean>true</is-read-only-bean>
Also, the refresh-period-in-seconds element in the sun-ejb-jar.xml file can be set to some value that specifies the rate at which the bean is refreshed. If this element is missing, no refresh occurs.
All requests in the same transaction context are routed to the same read-only bean instance. Set the allow-concurrent-access element to either true (to allow concurrent accesses) or false (to serialize concurrent access to the same read-only bean). The default is false.
For further information on these elements, refer to The sun-ejb-jar.xml File in Sun GlassFish Enterprise Server v2.1.1 Application Deployment Guide.