EJB 3.1 plan to have singleton EJB to address this issue. In the meantime, what you can do it to use a stateless EJB and store the data in a transient field. There will be N (= the pool size) instance of your bean, not only one, but it should already improve the performance. The application server ensure the only one bean is accessed at a time, so you don't need the "synchronized" keyword as with the typical singleton pattern.
If your data need to be also modified, I would suggest to store a timestamp in the databse. When changes are made, the timestamp is updated. Each bean need to check that the timestamp hasn't bee changed, otherwise it needs to reload the data. With this approach, you still pay the price of one select statement per access to the "cached" data, but it's probably less than to load the whole data everytime.
I think that some application server can have pool size be configured by EJB type (in this case you would set pool size=1 for this EJB), but I don't know if Glassfish has this option.
private transient MyData cache;
private transient long timestamp;
public MyData getMyData()
{
// the bean can be destroyed / recreated by the application server
// we can not expect the value to be set
if( cache == null )
{
// load timestamp
// load the data into variable "cache"
}
else
{
long newTimestamp;
// select timestamp in db and load it into variable "newTimestamp"
if( newTimestamp > timestamp )
{
timestamp = newTimestamp;
// reload the data into variable "cache"
}
}
return cache;
}
public void updateData( ... )
{
// update timestamp in database
// update the data in database
}
[Message sent by forum member 'ewernli' (ewernli)]
http://forums.java.net/jive/thread.jspa?messageID=254889