Hibernate + EhCache = java.io.NotSerializableException
Posted
技术标签:
【中文标题】Hibernate + EhCache = java.io.NotSerializableException【英文标题】: 【发布时间】:2011-03-24 15:05:22 【问题描述】:我现在正在做负载测试。在大约 900 个请求之后,我收到了这个错误:
[ 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)
这是我的 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
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'
【问题讨论】:
【参考方案1】:日志告诉我发生这种情况是因为查询缓存试图将您的org.company.domains.Hotel
对象之一写入磁盘。在负载测试期间可能会发生这种情况并不奇怪,因为在它尝试将其刷新到磁盘之前,您只允许内存中查询缓存中的 5 个元素。
您要么需要使org.company.domains.Hotel
实现java.io.Serializable
,要么为查询缓存设置overflowToDisk="false"
。
【讨论】:
但这可能是一个良性错误 - 它只是意味着实体未写入缓存。其他一切都会按预期工作,不是吗?以上是关于Hibernate + EhCache = java.io.NotSerializableException的主要内容,如果未能解决你的问题,请参考以下文章
HIbernate 3.5.1 - 我可以加入 EHCache 2.0.1 吗?
Hibernate 和 EHCache:maxElementsInMemory 是如何工作的?
Hibernate + EhCache = java.io.NotSerializableException
如何使用 Spring 清除所有 Hibernate 缓存(ehcache)?
Hibernate + Ehcache - IllegalArgumentException 发生调用复合 id 的 getter