我有一个使用NHibernate映射并在二级缓存(memcached)中缓存的类'Company'。我们的团队最近在这个类中添加了一个新的bool属性,它将存储在数据库中。
在我们的开发环境中一切正常,但是一旦我们部署到我们的临时环境(共享实时数据库),我们就开始收到以下错误:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at (Object , Object[] , SetterCallback )
at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValuesWithOptimizer(Object entity, Object[] values)
at NHibernate.Tuple.Entity.PocoEntityTuplizer.SetPropertyValues(Object entity, Object[] values)
at NHibernate.Persister.Entity.AbstractEntityPersister.SetPropertyValues(Object obj, Object[] values, EntityMode entityMode)
at NHibernate.Cache.Entry.CacheEntry.Assemble(Object[] values, Object result, Object id, IEntityPersister persister, IInterceptor interceptor, ISessionImplementor session)
at NHibernate.Cache.Entry.CacheEntry.Assemble(Object instance, Object id, IEntityPersister persister, IInterceptor interceptor, ISessionImplementor session)
at NHibernate.Event.Default.DefaultLoadEventListener.AssembleCacheEntry(CacheEntry entry, Object id, IEntityPersister persister, LoadEvent event)
at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromSecondLevelCache(LoadEvent event, IEntityPersister persister, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
我最好的猜测是NHibernate无法将旧的缓存条目(没有新属性)反序列化为新的Company对象。我相信我已经证实了这一点,因为我在暂存环境中禁用了二级缓存,ISE停止了。
所以我想我的问题是如果它不能反序列化缓存条目而不是冒泡异常,我们如何强制NHibernate进入数据库?还有其他人遇到过这个问题吗?
我想现在,我们将不得不部署第二级缓存,重新启动memcached服务器,然后重新启用二级缓存。但是,这种解决方案并不理想。如果有人有更好的建议,我会非常感激。
答案 0 :(得分:0)
作为感兴趣的任何人的更新,我按照我的帖子中列出的步骤进行了操作:
[...]我们将不得不部署第二级缓存,重新启动memcached服务器,然后重新启用二级缓存。
......一切正常。它比我们的正常部署更复杂,但我们没有任何错误。
答案 1 :(得分:0)
执行所有不必要的操作 - 关闭二级缓存并重新启动所有这些。我认为你真正想要的就是使缓存中的项目失效,使nhibernate进入数据库。
如果找到与memcached相关的gem - 您可以通过从telnet接口刷新整个缓存来使其无效。
telnet SomeServerInCluster 11211
flush_all
您已经通过重新启动所有memcached计算机完成了您想要完成的任务。
答案 2 :(得分:0)
你们是否使用缓存区域前缀?我实现的是,只要我们有核心定义更改,我们就会写入不同的缓存区域前缀。这类似于刷新缓存区域。
好处是,您不会遇到新定义和缓存的旧陈旧定义不匹配的问题。
缺点是这会降低性能,因为现在需要重建缓存。
为了减轻性能,您可以始终包含(作为部署过程的一部分)缓存加热器例程,在您看到应用程序的任何繁重流量之前填充缓存。
希望这有帮助。