Author |
Message |
10/14/2010 06:00:51
|
satya087
journeyman
Joined: 10/14/2010 05:58:35
Messages: 16
Offline
|
Hi I am using EhCache for our project, i used spring based annotation to create cache and mapped the cache in ehcache.xml. can you please suggest me how to load data to cache during application start
Please reply as soon as possible
|
|
|
10/15/2010 13:33:46
|
dwai
journeyman
Joined: 10/15/2010 13:05:54
Messages: 14
Offline
|
Hi ,
You can write a startup-class(servlet or something like that-load first) to load the entire cache with the data you require at the startup
Also please mention the server you are using if any.
Regards,
Dwaipayan
|
Dwaipayan |
|
|
10/15/2010 21:46:20
|
satya087
journeyman
Joined: 10/14/2010 05:58:35
Messages: 16
Offline
|
Hi,
Actually i had thought of writing a servlet to do the prepolulating of cache, but according to our design we want to go for bootstrapCacheLoaderFactory to do the same for us, i tried to override the load method of bootstrapCacheLoaderFactory. Our Database is called from the dao and then dao is configured via spring and its init method(to get the data from database) is called after the load method of bootstrapCacheLoaderFactory. can you suggest a way how to do it via bootstrapCacheLoaderFactory
|
|
|
10/16/2010 10:48:16
|
dwai
journeyman
Joined: 10/15/2010 13:05:54
Messages: 14
Offline
|
Hi,
Create a AppBootStrapCacheLoad that extends BootStrapCacheLoaderFactory.
Also u have the interface BootstrapCacheLoader which has the method load(EhCache ehcacheparam).
So once you get the same u can override that method and in the ehcache.sml configure your own defined class to bootstrapclassloader field.
Write the preloading mechanism in the load method and that should work fine.
Only thing is that it is a tightly couple mechanism
Regards,
Dwai
|
Dwaipayan |
|
|
10/18/2010 05:44:14
|
satya087
journeyman
Joined: 10/14/2010 05:58:35
Messages: 16
Offline
|
There is one issue in this. my custom bootstraploaderFactory has some properties which are configured in spring's xml file, how does the bootstrap loader makes sure that all the properties of bootstraploader is instantiated before it calls the load method,
|
|
|
10/18/2010 11:02:57
|
dwai
journeyman
Joined: 10/15/2010 13:05:54
Messages: 14
Offline
|
Hi
CustomBootstrapLoader extends BootstrapCacheLoaderFactory
This has the method named "createBootstrapCacheLoader" with java.util.Properties as its arguement/parameter.
U can read the properties before and then pass the properties to this method as argument.
This method returns BootstrapCacheLoader interface.
U can have this class or some other class implement this interface and override load() and create and instance to the interface and then called the load method.
Logically this should work out.
Please let me know whether this works out.
|
Dwaipayan |
|
|
10/19/2010 00:35:24
|
satya087
journeyman
Joined: 10/14/2010 05:58:35
Messages: 16
Offline
|
Sure will let you know, thank you for the approach
|
|
|
10/20/2010 01:44:11
|
satya087
journeyman
Joined: 10/14/2010 05:58:35
Messages: 16
Offline
|
Hi,
the createBootstrapCacheLoader takes properties as arguments as you said but problem is wheni create a customBootstrapLoader and it has some data members as datasource, and some jdbcConnectiontemplate, which are required for database connectivity, but these dependent datamembers are defined in applicationContext.xml. and the dependency injection is done spring.
But the bootstrap loader is called after the caches are initialised, so how does bootstraploader come to know that all the dependency injection are set to the datamembers of custom bootstraploader and now it needs to invoke the load method. because it doesnt know about the spring dependency injection it only knows that caches are initialised.And it might happen that caches are initialised before the beans are initialised and injected by spring container.
|
|
|
10/21/2010 00:14:47
|
satya087
journeyman
Joined: 10/14/2010 05:58:35
Messages: 16
Offline
|
Hi,
completed eager loading successfully, with the suggestions from dwai, and few modification done by me below are the approaches->>
(Spring based approach)
1) configure your ApplicationContext.xml as below
<bean id="statesDAO" class="com.testing.sales.input.investor.StatesDAO"
parent="baseDAOBean" />
<ehcache:annotation-driven cache-manager="ehCacheManager" />
<bean id="ehCacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>/WEB-INF/ehcache.xml</value>
</property>
</bean>
<bean id="ehCacheFactory" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref bean="ehCacheManager" />
</property>
<property name="bootstrapCacheLoader">
<ref bean="myBootstrapCacheLoaderFactory" />
</property>
</bean>
<bean id="myBootstrapCacheLoaderFactory" class="com.testing.sales.input.investor.MyBootstrapCacheLoaderFactory">
<property name="cacheManager">
<ref bean="ehCacheManager" />
</property>
<property name="statesDAO">
<ref bean="statesDAO" />
</property>
</bean>
ehCache.xml->
enter your cache entry->
<cache name="stateCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
memoryStoreEvictionPolicy="LFU" >
</cache>
Configure your custom bootstraploader
package com.testing.sales.input.investor;
import java.util.List;
import java.util.Properties;
import com.googlecode.ehcache.annotations.CacheException;
import com.ltg.db.DAOException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.bootstrap.BootstrapCacheLoader;
import net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory;
import net.sf.ehcache.loader.CacheLoaderFactory;
public class MyBootstrapCacheLoaderFactory extends BootstrapCacheLoaderFactory
implements BootstrapCacheLoader
{
public MyBootstrapCacheLoaderFactory() {
super();
// TODO Auto-generated constructor stub
}
StatesDAO statesDAO;
public StatesDAO getStatesDAO() {
return statesDAO;
}
public void setStatesDAO(StatesDAO statesDAO) {
this.statesDAO = statesDAO;
}
CacheManager cacheManager;
public CacheManager getCacheManager() {
return cacheManager;
}
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public BootstrapCacheLoader createBootstrapCacheLoader(Properties properties) {
// TODO Auto-generated method stub
return new MyBootstrapCacheLoaderFactory();
}
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
public boolean isAsynchronous() {
// TODO Auto-generated method stub
return false;
}
public void load(Ehcache myCache) throws CacheException {
// TODO Auto-generated method stub
System.out.println("load your cache with whatever you want....");
List keys = myCache.getKeys();
for (int i = 0; i < keys.size(); i++) {
System.out.println("keys->"+keys.get(i));
}
try {
getStatesDAO().findAllStates();
} catch (DAOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("load complete!");
}
}
StatesDAO->
package com.testing.sales.input.investor;
import java.util.ArrayList;
import java.util.List;
import com.ltg.db.*;
import com.ltg.db.cache.CacheManager;
import net.sf.ehcache.Cache;
public class StatesDAO{
//annotation based caching and the name of cache should be defined in ehcache.xml.
@Cacheable(cacheName="stateCache")
public List findAllStates() throws DAOException {
List dataList=new ArrayList();
//your call to database that returns a list of objects
return dataList;
}
}
|
|
|
10/21/2010 13:18:07
|
dwai
journeyman
Joined: 10/15/2010 13:05:54
Messages: 14
Offline
|
Thnks for the detailed update
|
Dwaipayan |
|
|
12/03/2010 06:46:56
|
apaliwal
praetor
Joined: 01/05/2010 20:52:24
Messages: 223
Offline
|
Thanks for Sharing ...
|
cheers
ashish
|
|
|
12/07/2010 11:13:01
|
jesmith
journeyman
Joined: 12/07/2010 11:10:41
Messages: 31
Offline
|
I am not seeing how this will solve my problem. I am not using the @Cacheable annotations, but seeing the same problem as originally described.
However, the issue seems to be that the cacheManager is creating a new instance of the BootstrapCacheLoaderFactory, and not using the one that Spring created. And it doesn't seem like there is a way to inject the cacheManager with the cacheLoaderFactory.
How exactly will this force the cacheManager to return the Spring injected copy of the BootStrapCacheLoaderFactory, instead of simply creating a new one that is not Spring aware?
Specifically, the source code for the Cache object expliticly calls
Code:
BootstrapCacheLoaderFactory factory = (BootstrapCacheLoaderFactory)
ClassLoaderUtil.createNewInstance(className);
The fact that this is calling for a newInstance will ensure that the returned object is not a Spring proxied object and therefore isn't Spring bean aware.
|
|
|
07/21/2011 01:07:45
|
rajoshi
seraphim
Joined: 07/04/2011 04:36:10
Messages: 1491
Offline
|
Issue seems to be resolved.Please let us know if more information is required.
|
Rakesh Joshi
Senior Consultant
Terracotta. |
|
|
11/17/2014 02:27:57
|
rahul065
neo
Joined: 11/17/2014 02:23:55
Messages: 1
Offline
|
Hi Team,
I have few doubts in the respective code posted here by satya087.
1) What is myCache.getKeys() in MyBootstrapCacheLoaderFactory class.
2) How to run the project.
3) what is the expected output after running the server.
please help me with the doubts raised.
Thanks in advance.
|
|
|
|