Hibernate + EhCache = java.io.NotSerializableException

Oleksandr picture Oleksandr · Aug 3, 2010 · Viewed 12.1k times · Source

I'm doing load test now. After approximate 900 requests i got this error:

[ 03.08.10 11:49:00.465] [Store org.hibernate.cache.StandardQueryCache Spool Thread] ERROR net.sf.ehcache.store.DiskStore  - org.hibernate.cache.StandardQueryCacheCache: Failed to write element to disk 'sql: select hotelfeatu0_.name as col_0_0_ from feature hotelfeatu0_ where hotelfeatu0_.class='org.company.domains.HotelFeatures' and hotelfeatu0_.lang=? and hotelfeatu0_.hotel_id=?; parameters: ; named parameters: {ht=100: 'Hotel', lng=en}'. Initial cause was org.company.domains.Hotel
java.io.NotSerializableException: org.company.domains.Hotel
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
    at java.util.HashMap.writeObject(HashMap.java:1001)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:416)
    at net.sf.ehcache.Element.writeObject(Element.java:729)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1461)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
    at net.sf.ehcache.util.MemoryEfficientByteArrayOutputStream.serialize(MemoryEfficientByteArrayOutputStream.java:75)
    at net.sf.ehcache.store.DiskStore.serializeElement(DiskStore.java:781)
    at net.sf.ehcache.store.DiskStore.writeElement(DiskStore.java:735)
    at net.sf.ehcache.store.DiskStore.writeOrReplaceEntry(DiskStore.java:729)
    at net.sf.ehcache.store.DiskStore.flushSpool(DiskStore.java:703)
    at net.sf.ehcache.store.DiskStore.throwableSafeFlushSpoolIfRequired(DiskStore.java:671)
    at net.sf.ehcache.store.DiskStore.spoolAndExpiryThreadMain(DiskStore.java:640)
    at net.sf.ehcache.store.DiskStore.access$900(DiskStore.java:68)
    at net.sf.ehcache.store.DiskStore$SpoolAndExpiryThread.run(DiskStore.java:1110)

Here is my ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false">

    <diskStore path="java.io.tmpdir/sweethome"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    />

    <cache
                name="org.hibernate.cache.StandardQueryCache"
                maxElementsInMemory="5"
                eternal="false"
                timeToLiveSeconds="120"
                overflowToDisk="true"
    />

</ehcache>

Hibernate config:

hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='org.hibernate.cache.EhCacheProvider'
    connection.useUnicode=true
    connection.characterEncoding='UTF-8'
    dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'
}

Answer

waxwing picture waxwing · Aug 3, 2010

The log tells me that this happens because the query cache tries to write one of your org.company.domains.Hotel objects on disk. Not surprising that this might happen during a load test, since you only allow 5 elements in the query cache in memory before it tries to flush it to disk.

You either need to make org.company.domains.Hotel implement java.io.Serializable, or set overflowToDisk="false" for the query cache.