我正在使用一个使用EJB 2的系统。该系统由两个独立的应用程序组成,一个用于用户管理,另一个是包含业务逻辑的实际应用程序。
在业务逻辑应用程序中,我有一个代表User的bean管理实体bean。应用程序从用户管理数据库读取信息,但不能修改。
每当在用户管理应用程序中修改用户时,业务逻辑应用程序就会收到用户已更改的通知。这是通过调用业务应用程序来实现的,以删除bean,这将导致Weblogic将其从缓存中删除并"删除"它(这没有做任何事情—请参阅下面的ejbRemove代码)。下次业务应用程序需要该用户时,它将从数据库重新加载该用户。
使用以下代码使单个用户无效:
try
{
UserHome home = (UserAuthHome) getHome("User", UserHome.class);
User ua = home.findByPrimaryKey(user);
ua.remove(); // This will remove a single cached User bean in the business logic application
}
catch ...
这工作得很好,但有时(特别是在进行开发时)我需要使业务应用程序中所有缓存的User bean 无效。我想用编程的方式来做这件事——启动管理控制台需要很长时间。有太多的用户,不能为每个用户做一个呼叫。
可能的解决方案包括:
——访问bean缓存并获取已缓存的User bean列表。
——告诉WLS废弃当前User bean缓存中的所有项,并从数据库中重新读取它们。
不幸的是,我不知道如何做这些。我试着寻找一个解决方案,但我的互联网搜索业力没有找到任何有用的。
附加信息:
持久性:
<persistence-type>Bean</persistence-type>
<reentrant>false</reentrant>
缓存:<entity-descriptor>
<entity-cache>
<max-beans-in-cache>500</max-beans-in-cache>
<concurrency-strategy>Exclusive</concurrency-strategy>
<cache-between-transactions>true</cache-between-transactions>
</entity-cache>
<persistence></persistence>
</entity-descriptor>
Bean代码(在业务应用程序中):
public void ejbLoad()
{
thisLogger().entering(getUser(m_ctx), "ejbLoad()");
// Here comes some code that connects to the user database and fetches the bean data.
...
}
public void ejbRemove()
{
// This method does nothing
}
public void ejbStore()
{
// This method does nothing
}
public void ejbPostCreate()
{
// This method is empty
}
/**
* Required by EJB spec.
* <p>
* This method always throws CreateException since this entity is read only.
* The remote reference should be obtained by calling ejbFindByPrimaryKey().
*
* @return
* @exception CreateException
* Always thrown
*/
public String ejbCreate()
throws CreateException
{
throw new CreateException("This entity should be called via ejbFindByPrimaryKey()");
}
我做了一些额外的研究,找到了解决问题的办法。
我可以使用weblogic.ejb.CachingHome.invalidateAll()
。但是,要做到这一点,我必须将bean的并发策略更改为ReadOnly
。显然,Exclusive
并发不能使home接口实现weblogic.ejb.CachingHome
:
<entity-descriptor>
<entity-cache>
<max-beans-in-cache>500</max-beans-in-cache>
<read-timeout-seconds>0</read-timeout-seconds>
<concurrency-strategy>ReadOnly</concurrency-strategy>
<cache-between-transactions>true</cache-between-transactions>
</entity-cache>
<persistence></persistence>
</entity-descriptor>
最后,我的新函数invalidateAllUsers
的代码:
public void invalidateAllUsers() {
logger.entering(getUser(ctx), "invalidateAll()"); // getUser returns a string with the current user ( context.getCallerPrincipal().getName() ).
try {
UserHome home = (UserAuthHome) getHome("User", UserHome.class); // Looks up the home interface
CachingHome cache = (CachingHome)home; // Sweet weblogic magic!
cache.invalidateAll();
} catch (RemoteException e) {
logger.severe(getUser(ctx), "invalidate(date)", "got RemoteException", e);
throw new EJBException(e);
}
}