sihu
asked on
How can I refresh the entitybean?
Hi friends,
In one entitybean, there is a private method refresh(AgentPK pk), here
we load the bean instance with data from back store. This method is called
in ejbLoad(). In refresh method, we first check isModified() for the flag,
if it is true, we do the refresh, if false we do not refresh. At the end of
refresh method, however, the modification flay was set to false :
setModified(false) so that this bean will not be refreshed as long as the
server is up.
The code is like this:
public void ejbLoad() throws RemoteException
{
logDebug("ejbLoad: " + context,100);
try {
// call the refresh method with the current primary key.
refresh ((AgentPK) context.getPrimaryKey ());
}
catch ( FinderException fe ) {
throw new RemoteException (fe.getMessage ());
}
}
private void refresh(AgentPK p_pk) throws FinderException, RemoteException
{
// If the EJB has not been modified, don't refresh it & short circuit!
if ( !isModified () ) {
logDebug("refresh: short circuited reloading of entity.",100);
return;
}
..........//do database connection and query ...//
//set this instance not to be refreshed again
setModified(false);
}
Now in my client side, we want to refresh the bean - loading most recent
data from database so that on the gui we will see the most recent data.
However, I cannot just change setModified(false) to true at the end of the
refresh method because that way I always get unnessary refreshes. My
difficulty is I cannot use setModified() directly in my client code because
I have only the pk or remote interface.
How and where would be appropriate for me to set the modification flag to
true?
Thank you in advance for your help.
James
In one entitybean, there is a private method refresh(AgentPK pk), here
we load the bean instance with data from back store. This method is called
in ejbLoad(). In refresh method, we first check isModified() for the flag,
if it is true, we do the refresh, if false we do not refresh. At the end of
refresh method, however, the modification flay was set to false :
setModified(false) so that this bean will not be refreshed as long as the
server is up.
The code is like this:
public void ejbLoad() throws RemoteException
{
logDebug("ejbLoad: " + context,100);
try {
// call the refresh method with the current primary key.
refresh ((AgentPK) context.getPrimaryKey ());
}
catch ( FinderException fe ) {
throw new RemoteException (fe.getMessage ());
}
}
private void refresh(AgentPK p_pk) throws FinderException, RemoteException
{
// If the EJB has not been modified, don't refresh it & short circuit!
if ( !isModified () ) {
logDebug("refresh: short circuited reloading of entity.",100);
return;
}
..........//do database connection and query ...//
//set this instance not to be refreshed again
setModified(false);
}
Now in my client side, we want to refresh the bean - loading most recent
data from database so that on the gui we will see the most recent data.
However, I cannot just change setModified(false) to true at the end of the
refresh method because that way I always get unnessary refreshes. My
difficulty is I cannot use setModified() directly in my client code because
I have only the pk or remote interface.
How and where would be appropriate for me to set the modification flag to
true?
Thank you in advance for your help.
James
By the way, you can read the article by downloading the electronic copy of the magazine issue at:
http://www.sys-con.com/java/
http://www.sys-con.com/java/
Hi, James.
My instinctive reaction is to say it sounds like you have a design/implementation defect. Either the bean values _can_ change at any time, in which case you have a high probability of defective behavior because of the caching implementation, or they _can't_ change in which case you don't really have a problem.
Really, bean value caching is a responsibility that you should leave to the container. The EJB specification defines three kinds of Entity EJB caching that can occur. Option A caching allows the container to assume that it "owns" the database. Changes will not occur except through the EJB instances of a single container. As such, the container can read the EJB state once and then hold it between transactions. Option C caching is exactly the opposite -- EJB state must be refreshed at the beginning of each transaction and flushed at the end of a transaction. Option B is a somewhat confusing "middle-ground". Depending on your container, it may support some or all of these options.
So -- 1) determine whether the bean values can change and 2) determine the commit level caching option of your container. If your bean values can change external to the EJB container then the current caching mechanism is likely a defective optimization that should be removed. If bean values cannot change except through the entity EJB, you have only one container instance in your deployment environment, and your container supports Option A caching, then remove the "custom" caching in favor of container-managed cache. Either way you don't want clients to be forced to know when they must refresh bean values.
For reference, the EJB specs which describe the commit options are available here:
http://java.sun.com/products/ejb/docs.html
Best regards,
Jim Cakalic
My instinctive reaction is to say it sounds like you have a design/implementation defect. Either the bean values _can_ change at any time, in which case you have a high probability of defective behavior because of the caching implementation, or they _can't_ change in which case you don't really have a problem.
Really, bean value caching is a responsibility that you should leave to the container. The EJB specification defines three kinds of Entity EJB caching that can occur. Option A caching allows the container to assume that it "owns" the database. Changes will not occur except through the EJB instances of a single container. As such, the container can read the EJB state once and then hold it between transactions. Option C caching is exactly the opposite -- EJB state must be refreshed at the beginning of each transaction and flushed at the end of a transaction. Option B is a somewhat confusing "middle-ground". Depending on your container, it may support some or all of these options.
So -- 1) determine whether the bean values can change and 2) determine the commit level caching option of your container. If your bean values can change external to the EJB container then the current caching mechanism is likely a defective optimization that should be removed. If bean values cannot change except through the entity EJB, you have only one container instance in your deployment environment, and your container supports Option A caching, then remove the "custom" caching in favor of container-managed cache. Either way you don't want clients to be forced to know when they must refresh bean values.
For reference, the EJB specs which describe the commit options are available here:
http://java.sun.com/products/ejb/docs.html
Best regards,
Jim Cakalic
ASKER
Thank you jpk and Jim,
Jpk, I can have a simpler option to set a refresh flag when I load my hierarchy in the cache. The problem now is after I have updated the bean data on serverside, my client side(gui) still gets the old data. I wonder there must be two sets of data in the cache and even though I log out and relogin as a new user, I still cannot get the latest data that have been updated on the server side.
Are they cached to different places?
James
Jpk, I can have a simpler option to set a refresh flag when I load my hierarchy in the cache. The problem now is after I have updated the bean data on serverside, my client side(gui) still gets the old data. I wonder there must be two sets of data in the cache and even though I log out and relogin as a new user, I still cannot get the latest data that have been updated on the server side.
Are they cached to different places?
James
What application server are you using?
When you log out the entity been shoud be returned to the object pool, when you reaquire it, after an ejbActivate() call, ejbLoad() is called inmediatley.
This leads to three possibilities I can think of:
1.- Your code to modify the value of your flag is not working.
2.- Yur application server uses some form of environment property to handle entity bean persistance and you are not setting it correctly
2.- Your app server cashes the DB calls (example Oracle IAS9i) and you have incorectly set the app servers cahe configuration.
Of these three, option 1 and 2 seems the most likely.
When you log out the entity been shoud be returned to the object pool, when you reaquire it, after an ejbActivate() call, ejbLoad() is called inmediatley.
This leads to three possibilities I can think of:
1.- Your code to modify the value of your flag is not working.
2.- Yur application server uses some form of environment property to handle entity bean persistance and you are not setting it correctly
2.- Your app server cashes the DB calls (example Oracle IAS9i) and you have incorectly set the app servers cahe configuration.
Of these three, option 1 and 2 seems the most likely.
ASKER
I looked into my code again. My gui side getting data via a Proxy which implements the remote interface of my bean. In this proxy class, there is a updateCache(EJBChangeEvent
ASKER
Hi jpk, to answer your question, I am using weblogic 5.1.
The flay problems I have solved. I guess my problem now is to figure out why the proxy is not working in updating cache.
The flay problems I have solved. I guess my problem now is to figure out why the proxy is not working in updating cache.
ASKER
Hi Jim and JPK,
Thank you for your responses. After reading your comments and reading weblogic documents, I did not see I should do anything with my deployment xmls. Here I'd like to post them to you so that you may give me better directions. Thank you.
*********** **
* ejb-jar.xml
**************
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>com.app.cajims.e jb.entityb ean.AgentH ome</ejb-n ame>
<home>com.app.cajims.ejb.e ntitybean. agent.Agen tHome</hom e>
<remote>com.app.cajims.ejb .entitybea n.agent.Ag entEJB</re mote>
<ejb-class>com.app.cajims. ejb.entity bean.agent .AgentBean </ejb-clas s>
<persistence-type>Bean</pe rsistence- type>
<prim-key-class>com.app.ca jims.ejb.e ntitybean. agent.Agen tPK</prim- key-class>
<reentrant>True</reentrant >
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>com.app.cajims.e jb.entityb ean.AgentH ome</ejb-n ame>
<method-intf>Remote</metho d-intf>
<method-name>*</method-nam e>
</method>
<trans-attribute>Required< /trans-att ribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
***********************
*weblogic-ejb-jar.xml
**********************
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>com.app.cajims.e jb.entityb ean.AgentH ome</ejb-n ame>
<caching-descriptor>
<max-beans-in-free-pool>10 0</max-bea ns-in-free -pool>
<max-beans-in-cache>3000</ max-beans- in-cache>
<idle-timeout-seconds>3600 </idle-tim eout-secon ds>
</caching-descriptor>
<persistence-descriptor>
<delay-updates-until-end-o f-tx>false </delay-up dates-unti l-end-of-t x>
</persistence-descriptor>
<jndi-name>com.app.cajims. ejb.entity bean.Agent Home</jndi -name>
<transaction-isolation>
<isolation-level>TRANSACTI ON_READ_CO MMITTED</i solation-l evel>
<method>
<ejb-name>com.app.cajims.e jb.entityb ean.AgentH ome</ejb-n ame>
<method-intf>Remote</metho d-intf>
<method-name>*</method-nam e>
</method>
</transaction-isolation>
</weblogic-enterprise-bean >
</weblogic-ejb-jar>
Thank you for your responses. After reading your comments and reading weblogic documents, I did not see I should do anything with my deployment xmls. Here I'd like to post them to you so that you may give me better directions. Thank you.
*********** **
* ejb-jar.xml
**************
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>com.app.cajims.e
<home>com.app.cajims.ejb.e
<remote>com.app.cajims.ejb
<ejb-class>com.app.cajims.
<persistence-type>Bean</pe
<prim-key-class>com.app.ca
<reentrant>True</reentrant
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>com.app.cajims.e
<method-intf>Remote</metho
<method-name>*</method-nam
</method>
<trans-attribute>Required<
</container-transaction>
</assembly-descriptor>
</ejb-jar>
***********************
*weblogic-ejb-jar.xml
**********************
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>com.app.cajims.e
<caching-descriptor>
<max-beans-in-free-pool>10
<max-beans-in-cache>3000</
<idle-timeout-seconds>3600
</caching-descriptor>
<persistence-descriptor>
<delay-updates-until-end-o
</persistence-descriptor>
<jndi-name>com.app.cajims.
<transaction-isolation>
<isolation-level>TRANSACTI
<method>
<ejb-name>com.app.cajims.e
<method-intf>Remote</metho
<method-name>*</method-nam
</method>
</transaction-isolation>
</weblogic-enterprise-bean
</weblogic-ejb-jar>
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
[paq'ed/points refunded]
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
sudhakar_koundinya
EE Cleanup Volunteer
---------------------
If you feel that your question was not properly addressed, or that none of the comments received were appropriate answers, please post your concern in THIS thread.
I will leave a recommendation in the Cleanup topic area that this question is:
[paq'ed/points refunded]
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
sudhakar_koundinya
EE Cleanup Volunteer
---------------------
If you feel that your question was not properly addressed, or that none of the comments received were appropriate answers, please post your concern in THIS thread.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Universal Wrapper for Entity Beans by Andrei Povodyrev and Alan Askew.
Java Developers Journal June, 2001.
The article describes a parent class and interface that allows you more flexibility in the definition of you beans than the dafault specs allow for.
With the added flexibility, you could change the modify class in a service class method and have it delegate to refresh.