
It is straight forward to create a new cache space with ehCache in Java. However, it is a bit harder to add this cache in HAC / Region cache system.
Region cache advantage is to
This article is explaining step by step how to create this type of cache.
First step is to create a new simple region cache type that simple takes two arguments: key and value.
import de.hybris.platform.regioncache.CacheValueLoadException;
import de.hybris.platform.regioncache.CacheValueLoader;
import de.hybris.platform.regioncache.key.CacheKey;
import de.hybris.platform.regioncache.region.impl.EHCacheRegion;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class SimpleEHCacheRegion extends EHCacheRegion {
// Contructor to setting up cache option
public SimpleEHCacheRegion(final String name,
final int maxEntries, final String evictionPolicy,
final boolean exclusiveComputation, final boolean statsEnabled,
final Long ttlSeconds) {
super(name, maxEntries, evictionPolicy, exclusiveComputation, statsEnabled, ttlSeconds);
}
[...]
}
Get and Put must be adapted to include type notion into the key
public Object get(final Object key) {
// key computation by including hardcoded type
final SimpleGenericCacheKey genericCacheKey
= generateGenericCacheKey(key);
return super.get(genericCacheKey);
}
Put method is a bit more complex
public void put(final Object key, final Object object) {
// key computation by including hardcoded type
final SimpleGenericCacheKey genericCacheKey = generateGenericCacheKey(key);
// loader to insert value into the cache
final DefaultCacheValueLoaderImpl<Object> loader = new DefaultCacheValueLoaderImpl<Object>();
loader.setValue(object);
// remove previous entry if exists
remove(genericCacheKey);
super.getWithLoader(genericCacheKey, loader);
}
HandledTypes method must be override to remove super() logic
@Override
public void setHandledTypes(final String[] handledTypes){
//
}
Key generator based on hardcoded type should look like
private SimpleGenericCacheKey generateGenericCacheKey(final Object key) {
if (key instanceof SimpleGenericCacheKey) {
return (SimpleGenericCacheKey) key;
} else { return new SimpleGenericCacheKey(key, "JavaObject");}
}
And inner Cache Value Loader class should look like
private class DefaultCacheValueLoaderImpl<V> implements CacheValueLoader<V> {
private V obj;
public DefaultCacheValueLoaderImpl() {
super();
}
@Override
public V load(final CacheKey arg0) throws CacheValueLoadException {
return this.obj;
}
@SuppressWarnings("unchecked")
public void setValue(final Object obj) {
this.obj = (V) obj;
}
}
Second step is to create a cache key class that will define key struct
import de.hybris.platform.regioncache.key.CacheKey;
import de.hybris.platform.regioncache.key.CacheUnitValueType;
public class SimpleGenericCacheKey implements CacheKey {
// key itself
private final Object key;
private String tenant;
private final Object typeCode;
public SimpleGenericCacheKey(final Object key, final String typeCode) {
this.key = key;
this.typeCode = typeCode;
this.tenant = "master";
}
[...]
}
Then classic method to compare two instance must be override.
hashCode() example
@Override
public int hashCode() {
return this.key.hashCode();
}
equals() example
@Override
public boolean equals(final Object o) {
if (o == null){
return false;
}
else if (o == this) {
return true;
} else if (this.getClass() != o.getClass()) {
return false;
}
else {
final SimpleGenericCacheKey command = (SimpleGenericCacheKey) o;
return this.key.equals(command.key);
}
}
Last step is to declare the beans associated
<!-- abstract instance that can be reused for declaring many different caches -->
<bean abstract="true" class="...SimpleEHCacheRegion" id="simpleCacheRegion">
<constructor-arg name="evictionPolicy" value="LRU"/>
<constructor-arg name="statsEnabled" value="true"/>
<constructor-arg name="exclusiveComputation" value="false"/>
</bean>
<!-- concrete instance example -->
<bean id="customCacheRegion" parent="simpleCacheRegion">
<constructor-arg name="name" value="customCacheRegion"/>
<constructor-arg name="maxEntries" value="10000"/>
</bean>
New cache bean must be recorded in HAC list
<!-- Add the cache region to the list displayed in the hac -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="cacheRegionsList"/>
<property name="targetMethod" value="add"/>
<property name="singleton" value="true"/>
<property name="arguments">
<ref bean="customCacheRegion" />
</property>
</bean>
new way
<bean id="customCacheRegionRegistrar" class="de.hybris.platform.regioncache.region.CacheRegionRegistrar" c:region-ref="customCacheRegion" />
Spring xml file must be set in global context (project.properties)
# Cache regions need to go to the global context
custom.global-context=custom-cache-spring.xml
Then, we should see our new cache region in HAC list from https://localhost:9002/monitoring/cache
Custom EhCache integration into HAC Cache Region is possible and it demands a little development effort where we know how to do it.
And in case official SAP Commerce document is not rich enough, you should not hesitate to ask SAP Expert Services help to perform some customization you needed.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
4 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |