In one of our products, we are experiencing intermittent ejb entity bean caching
problems on out weblogic 6.1 SP1 servers in our cluster.
Intermittently, when we do a findByPrimaryKey(), we get the wrong EJB reference back.
It doesn't return the correct entity remote reference for the primary key.
Sometimes, we get exceptions like:
####<Jun 3, 2002 5:07:53 PM EDT> <Warning> <JTA> <epccbcbeas10> <cbc10> <ExecuteThread:
'9' for queue: 'default'> <> <> <000000> <Ignoring error in afterCompletion. Object=weblogic.ejb20.internal.TxManager$TxListener@4db8c4>
javax.ejb.EJBException: The EJB Lock Manager has received an unlock request from
EJB:SearchCriteriaBean with primary key:19720718. However, this primary key could
not be found in the Lock Manager. This indicates either an EJB container bug, or
the equals and hashCode methods for the primary key class:com.collegeboard.collegesearch.criteria.ejb.SearchCriteriaPK
are implemented incorrectly. Please check the equals and hashCode implementations.
at weblogic.ejb20.locks.ExclusiveLockManager$LockBucket.unlock(ExclusiveLockManager.java:576)
at weblogic.ejb20.locks.ExclusiveLockManager.unlock(ExclusiveLockManager.java:291)
at weblogic.ejb20.manager.ExclusiveEntityManager.afterCompletion(ExclusiveEntityManager.java:461)
at weblogic.ejb20.internal.TxManager$TxListener.afterCompletion(TxManager.java:421)
at weblogic.transaction.internal.ServerSCInfo.callAfterCompletions(ServerSCInfo.java:464)
at weblogic.transaction.internal.ServerTransactionImpl.callAfterCompletions(ServerTransactionImpl.java:2109)
at weblogic.transaction.internal.ServerTransactionImpl.setCommitted(ServerTransactionImpl.java:2081)
at weblogic.transaction.internal.ServerTransactionImpl.globalRetryCommit(ServerTransactionImpl.java:1942)
at weblogic.transaction.internal.ServerTransactionImpl.globalCommit(ServerTransactionImpl.java:1886)
at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:221)
at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:190)
at weblogic.ejb20.internal.BaseEJBObject.postInvoke(BaseEJBObject.java:231)
at com.collegeboard.collegesearch.searchsession.ejb.PerformSearchBean_hwtp47_EOImpl.loadSavedSearchCriteria(PerformSearchBean_hwtp47_EOImpl.java:588)
at jsp_servlet._search._my.__startsavedsearch._jspService(__startsavedsearch.java:420)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:27)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:265)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:200)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:2456)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2039)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:139)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)
####<Jun 3, 2002 5:14:32 PM EDT> <Info> <WebLogicServer> <epccbcbeas10> <cbc10> <ExecuteThread:
'3' for queue: 'default'> <> <> <000274> <Removing "ClientContext - id: '#|cbc10|751.1022686072598',
bound: 'false', dead: 'false'" because of soft disconnect timeout.>
Our primary key looks like:
package com.collegeboard.collegesearch.college.ejb;
import java.io.Serializable;
public class CollegePK implements Serializable {
public Integer collegeId;
public CollegePK() {}
public CollegePK(Integer id)
{
collegeId = id;
}
public boolean equals(Object obj)
{
if (obj == null || !(obj instanceof CollegePK))
return false;
else if (((CollegePK)obj).collegeId.intValue() == collegeId.intValue())
return true;
else
return false;
}
public int hashCode()
{
return collegeId.hashCode();
}
public String toString()
{
return new String("College ID is: " + collegeId);
}
}//end CollegePK
It may not be the most efficient, but I hope it is right.
Our ejb-jar.xml looks like:
<weblogic-enterprise-bean>
<ejb-name>CollegeBean</ejb-name>
<caching-descriptor>
<max-beans-in-free-pool>50</max-beans-in-free-pool>
<max-beans-in-cache>2500</max-beans-in-cache>
<idle-timeout-seconds>3600</idle-timeout-seconds>
<cache-strategy>Read-Only</cache-strategy>
<read-timeout-seconds>3600</read-timeout-seconds>
</caching-descriptor>
<persistence-descriptor>
<is-modified-method-name>isModified</is-modified-method-name>
</persistence-descriptor>
<reference-descriptor>
<resource-description>
<res-ref-name>collegePool</res-ref-name>
<jndi-name>collegePool</jndi-name>
</resource-description>
</reference-descriptor>
<jndi-name>college.CollegeHome</jndi-name>
</weblogic-enterprise-bean>
Transactions are TX_REQUIRED for the read-only bean.
Please help.
Thanks.
--Bahar
Have a look at
Bahar Limaye wrote:
--
Rajesh Mirchandani
Developer Relations Engineer
BEA Support
Can you give me a bug description and solution for this fix?
Is there anything that I can do on my production system to isolate the problem?
Thanks.
><!doctype html public "-//w3c//dtd html 4.0 transitional//en">
><html>
>This has been fixed in SP2.
><p>Rajesh Mirchandani wrote:
><blockquote TYPE=CITE>Have a look at
><p><a href="http://newsgroups.bea.com/cgi-bin/dnewsweb?utag=&group=weblogic.developer.interest.ejb&xrelated=30288&cmd_thread_next.x=70&cmd_thread_next.y=11">http://newsgroups.bea.com/cgi-bin/dnewsweb?utag=&group=weblogic.developer.interest.ejb&xrelated=30288&cmd_thread_next.x=70&cmd_thread_next.y=11</a>
><p>Bahar Limaye wrote:
><p>> Hello,
><br>>
><br>> In one of our products, we are experiencing intermittent ejb entity
>bean caching
><br>> problems on out weblogic 6.1 SP1 servers in our cluster.
><br>>
><br>> Intermittently, when we do a findByPrimaryKey(), we get the wrong
>EJB reference back.
><br>>Â It doesn't return the correct entity remote reference for the
>primary key.
><br>>
><br>> Sometimes, we get exceptions like:
><br>>
><br>> ####<Jun 3, 2002 5:07:53 PM EDT> <Warning> <JTA> <epccbcbeas10>
><cbc10> <ExecuteThread:
><br>> '9' for queue: 'default'> <> <> <000000> <Ignoring error
>in afterCompletion. Object=weblogic.ejb20.internal.TxManager$TxListener@4db8c4>
><br>>
><br>> javax.ejb.EJBException: The EJB Lock Manager has received an unlock
>request from
><br>> EJB:SearchCriteriaBean with primary key:19720718. However, this primary
>key could
><br>> not be found in the Lock Manager. This indicates either an EJB container
>bug, or
><br>> the equals and hashCode methods for the primary key class:com.collegeboard.collegesearch.criteria.ejb.SearchCriteriaPK
><br>> are implemented incorrectly. Please check the equals and hashCode
>implementations.
><br>>Â Â Â Â Â Â Â Â at weblogic.ejb20.locks.ExclusiveLockManager$LockBucket.unlock(ExclusiveLockManager.java:576)
><br>>Â Â Â Â Â Â Â Â at weblogic.ejb20.locks.ExclusiveLockManager.unlock(ExclusiveLockManager.java:291)
><br>>Â Â Â Â Â Â Â Â at weblogic.ejb20.manager.ExclusiveEntityManager.afterCompletion(ExclusiveEntityManager.java:461)
><br>>Â Â Â Â Â Â Â Â at weblogic.ejb20.internal.TxManager$TxListener.afterCompletion(TxManager.java:421)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerSCInfo.callAfterCompletions(ServerSCInfo.java:464)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerTransactionImpl.callAfterCompletions(ServerTransactionImpl.java:2109)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerTransactionImpl.setCommitted(ServerTransactionImpl.java:2081)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerTransactionImpl.globalRetryCommit(ServerTransactionImpl.java:1942)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerTransactionImpl.globalCommit(ServerTransactionImpl.java:1886)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:221)
><br>>Â Â Â Â Â Â Â Â at weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:190)
><br>>Â Â Â Â Â Â Â Â at weblogic.ejb20.internal.BaseEJBObject.postInvoke(BaseEJBObject.java:231)
><br>>Â Â Â Â Â Â Â Â at com.collegeboard.collegesearch.searchsession.ejb.PerformSearchBean_hwtp47_EOImpl.loadSavedSearchCriteria(PerformSearchBean_hwtp47_EOImpl.java:588)
><br>>Â Â Â Â Â Â Â Â at jsp_servlet._search._my.__startsavedsearch._jspService(__startsavedsearch.java:420)
><br>>Â Â Â Â Â Â Â Â at weblogic.servlet.jsp.JspBase.service(JspBase.java:27)
><br>>Â Â Â Â Â Â Â Â at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:265)
><br>>Â Â Â Â Â Â Â Â at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:200)
><br>>Â Â Â Â Â Â Â Â at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:2456)
><br>>Â Â Â Â Â Â Â Â at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2039)
><br>>Â Â Â Â Â Â Â Â at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:139)
><br>>Â Â Â Â Â Â Â Â at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)
><br>> ####<Jun 3, 2002 5:14:32 PM EDT> <Info> <WebLogicServer>
><epccbcbeas10> <cbc10> <ExecuteThread:
><br>> '3' for queue: 'default'> <> <> <000274> <Removing "ClientContext
>- id: '#|cbc10|751.1022686072598',
><br>> bound: 'false', dead: 'false'" because of soft disconnect timeout.>
><br>>
><br>> Our primary key looks like:
><br>>
><br>> package com.collegeboard.collegesearch.college.ejb;
><br>>
><br>> import java.io.Serializable;
><br>>
><br>> public class CollegePK implements Serializable {
><br>>
><br>>Â Â Â Â Â Â Â Â public Integer collegeId;
><br>>
><br>>Â Â Â Â Â Â Â Â public CollegePK()
>{}
><br>>
><br>>Â Â Â Â Â Â Â Â public CollegePK(Integer
>id)
><br>>Â Â Â Â Â Â Â Â {
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>collegeId = id;
><br>>Â Â Â Â Â Â Â Â }
><br>>
><br>>Â Â Â Â Â Â Â Â public boolean equals(Object
>obj)
><br>>Â Â Â Â Â Â Â Â {
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>if (obj == null || !(obj instanceof CollegePK))
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>return false;
><br>>Â Â Â Â Â Â Â Â else if (((CollegePK)obj).collegeId.intValue()
>== collegeId.intValue())
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>return true;
><br>>Â Â Â Â Â Â Â Â else
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>return false;
><br>>Â Â Â Â Â Â Â Â }
><br>>
><br>>Â Â Â Â Â Â Â Â public int hashCode()
><br>>Â Â Â Â Â Â Â Â {
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>return collegeId.hashCode();
><br>>Â Â Â Â Â Â Â Â }
><br>>
><br>>Â Â Â Â Â Â Â Â public String toString()
><br>>Â Â Â Â Â Â Â Â {
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
>return new String("College ID is: " + collegeId);
><br>>Â Â Â Â Â Â Â Â }
><br>>
><br>> }//end CollegePK
><br>>
><br>> It may not be the most efficient, but I hope it is right.
><br>>
><br>> Our ejb-jar.xml looks like:
><br>>
><br>> <weblogic-enterprise-bean>
><br>>Â Â Â Â Â Â Â Â <ejb-name>CollegeBean</ejb-name>
><br>>Â Â Â Â Â Â Â Â <caching-descriptor>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><max-beans-in-free-pool>50</max-beans-in-free-pool>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><max-beans-in-cache>2500</max-beans-in-cache>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><idle-timeout-seconds>3600</idle-timeout-seconds>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><cache-strategy>Read-Only</cache-strategy>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><read-timeout-seconds>3600</read-timeout-seconds>
><br>>Â Â Â Â Â Â Â Â </caching-descriptor>
><br>>Â Â Â Â Â Â Â Â <persistence-descriptor>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><is-modified-method-name>isModified</is-modified-method-name>
><br>>Â Â Â Â Â Â Â Â </persistence-descriptor>
><br>>Â Â Â Â Â Â Â Â <reference-descriptor>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
><resource-description>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
><res-ref-name>collegePool</res-ref-name>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
><jndi-name>collegePool</jndi-name>
><br>>Â Â Â Â Â Â Â Â Â Â Â Â
></resource-description>
><br>>Â Â Â Â Â Â Â Â </reference-descriptor>
><br>>Â Â Â Â Â Â Â Â <jndi-name>college.CollegeHome</jndi-name>
><br>>Â Â Â Â </weblogic-enterprise-bean>
><br>>
><br>> Transactions are TX_REQUIRED for the read-only bean.
><br>>
><br>> Please help.
><br>>
><br>> Thanks.
><br>>
><br>> --Bahar
><p>--
><br>Rajesh Mirchandani
><br>Developer Relations Engineer
><br>BEA Support</blockquote>
>
><p>--
><br>Rajesh Mirchandani
><br>Developer Relations Engineer
><br>BEA Support
><br>Â </html>
>
>
What you probably see is related to the mutability of your PK class.
Can you make the collegeId private in your PK class and not provide
accessor to modify it.
If your design does not allow that, try placing a debug statement at any
place that it might be modified and print the old and new values -- if
they are different, then that is your problem and the fix is not to
mutate the PK instance once the container has a hold of it.
HTH
--dejan