John Glassman
John Glassman

Reputation: 311

ehcache error serializing key for distributed config with terracotta server

I'm trying to configure terracotta server to work with a spring/mybatis application and I'm getting the following error. I'm not sure if that means the key itself or the value returned from the key could not be serialized. The caching worked fine as a local cache, but now has the issue trying to work with the server. I need a clue why this is not able to be serialized. Thanks.

So I got a clue from this How do you serialize a Spring Bean (spring 3) that it may be something to do with lack of session scope. These errors happen when I am starting up Tomcat and the first webpage is loading. I added implements java.io.Serializable to the Site bean class and that moved me past that error to the next bean that was getting called. After adding this to many beans I'm wondering if A, is this the right thing to do and will there be any side effects from forcing the implements java.io.Serializable on these spring classes? And B: is there a better way do this as I have many beans in this application?

SEVERE: Servlet.service() for servlet [ezreg] in context with path [] threw exception [Request processing failed; nested exception is net.sf.ehcache.CacheException: The value com.trifecta.src.ezreg.beans.Site@655ad5d5 for key getSiteByHostname127.0.0.1 is not Serializable. Consider using Element.getObjectValue()] with root cause
net.sf.ehcache.CacheException: The value com.trifecta.src.ezreg.beans.Site@655ad5d5 for key getSiteByHostname127.0.0.1 is not Serializable. Consider using Element.getObjectValue()
    at net.sf.ehcache.Element.getValue(Element.java:326)
    at net.sf.ehcache.ElementData.<init>(ElementData.java:35)
    at net.sf.ehcache.EternalElementData.<init>(EternalElementData.java:19)
    at org.terracotta.modules.ehcache.store.ValueModeHandlerSerialization.createElementData(ValueModeHandlerSerialization.java:48)
    at org.terracotta.modules.ehcache.store.ClusteredStore.doPut(ClusteredStore.java:745)
    at org.terracotta.modules.ehcache.store.ClusteredStore.putInternal(ClusteredStore.java:291)
    at org.terracotta.modules.ehcache.store.ClusteredStore.put(ClusteredStore.java:263)
    at org.terracotta.modules.ehcache.store.ClusteredSafeStore.put(ClusteredSafeStore.java:247)
    at org.terracotta.modules.ehcache.store.nonstop.NonStopStoreWrapper.put(NonStopStoreWrapper.java:820)
    at net.sf.ehcache.Cache.putInternal(Cache.java:1617)
    at net.sf.ehcache.Cache.put(Cache.java:1543)
    at net.sf.ehcache.Cache.put(Cache.java:1508)
    at org.springframework.cache.ehcache.EhCacheCache.put(EhCacheCache.java:121)
    at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:85)
    at org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:784)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:417)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy56.getSiteByHostname(Unknown Source)
    at com.trifecta.src.ezreg.daos.SiteDaoImpl.getSiteByHostname(SiteDaoImpl.java:35)


doa method:
    public Site getSiteByHostname(String hostname) {        
        return getSiteMapper().getSiteByHostname(hostname);
    }

mapper method:

@Cacheable(cacheNames="siteCache", key="#root.methodName.concat(#root.args)")
Site getSiteByHostname(String hostname);

Site bean returned:

package com.trifecta.src.ezreg.beans;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement
public class Site {
    public static String ADMIN_CURRENT_SITE = "adminCurrentSite";
    public static String _CURRENT_SITE = "currentSite";

    @XmlAttribute
    private Long id;

    @XmlAttribute
    private String name;

    @XmlAttribute
    private String supportphonenumber;

    @XmlElement
    private SitePreference sitePreference;

    @XmlElement
    private SiteInterfaceDevice siteInterfaceDevice;

    @XmlElement
    private SitePdfFormat sitePdfFormat;

    @XmlAttribute
    private boolean ecum; 

    @XmlTransient
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    @XmlTransient
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @XmlTransient
    public SiteInterfaceDevice getSiteInterfaceDevice() {
        return siteInterfaceDevice;
    }
    public void setSiteInterfaceDevice(SiteInterfaceDevice siteInterfaceDevice) {
        this.siteInterfaceDevice = siteInterfaceDevice;
    }
    @XmlTransient
    public SitePdfFormat getSitePdfFormat() {
        return sitePdfFormat;
    }
    public void setSitePdfFormat(SitePdfFormat sitePdfFormat) {
        this.sitePdfFormat = sitePdfFormat;
    }
    @XmlTransient
    public SitePreference getSitePreference() {
        return sitePreference;
    }
    public void setSitePreference(SitePreference sitePreference) {
        this.sitePreference = sitePreference;
    }
    @XmlTransient
    public String getSupportphonenumber() {
        return supportphonenumber;
    }
    public void setSupportphonenumber(String supportphonenumber) {
        this.supportphonenumber = supportphonenumber;
    }
    @XmlTransient
    public boolean getEcum() {
        return ecum;
    }
    public void setEcum(boolean ecum) {
        this.ecum = ecum;
    }
}


public class Site implements java.io.Serializable{
    public static String ADMIN_CURRENT_SITE = "adminCurrentSite";
    public static String _CURRENT_SITE = "currentSite";

Upvotes: 1

Views: 1584

Answers (1)

Louis Jacomet
Louis Jacomet

Reputation: 14500

When caching locally, you can have a setup using heap memory only and thus there is no requirement on your keys / values stored in the cache.

However the moment you move to clustering, or actually any other caching tier than heap, then your keys and values must implement Serializable as this is the only way we can store / ship over the wire your mappings.

And so clearly in your case the type com.trifecta.src.ezreg.beans.Site does not implement Serializable.

You have two options:

  1. Update the type definition to implement Serializable and make sure it is true - that is it only has Serializable fields
  2. Convert the non serializable value in one that can be serialized.

Note that with Ehcache 3 you would have the option of specifying a custom serializer for your type that would not limit you to Java serialization.

Upvotes: 2

Related Questions