无法序列化为二级缓存

时间:2018-03-13 20:02:13

标签: java jdo datanucleus jedis

我使用datanucleus& amp录制了一些错误的配置。 JDO在一个独立的Java Web应用程序中(使用Jetty,Servlets [是的架构有点古老]和春天)。

我们目前正在开发一个新版本;最初的项目在过去3年里没有任何依赖更新;所以我们希望拥有那些不错的安全性,性能和安全性。功能升级,但正如预期的那样,升级并不容易。

我们遇到的大多数问题已经解决了,但一个变得非常乏味的问题却没有:

  • 当服务器启动时,它会检查数据库中是否有默认用户;这是蒙戈。如果没有用户,则创建默认用户。无论如何,服务器都会启动。

我们正在使用datanucleus + JDO来访问底层数据库;主要是因为它已经存在,因为大多数系统真的与它绑在一起。到目前为止,我们可以确认datanucleus可以读取数据库(调试器显示来自数据库的非空结果,其正确表示默认用户;以及来自活动端点的一些其他虚拟结果)。但是当datanucleus尝试缓存结果时,它就会陷入死胡同。

错误堆栈如下:

GRAVE: exception catched
javax.jdo.JDOException: Failed to set object CachedPC : cls=mobi.allshoppings.model.User version=null loadedFlags=[YYYYYYYYYYYYYYYYY] with id com.inodes.datanucleus.model.Key:User("admin") into Redis cache
    at org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:680)
    at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1747)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:144)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:108)
    at mobi.allshoppings.bdb.tools.BasicDataBuilder.warmUp(BasicDataBuilder.java:49)
    at mobi.allshoppings.bdb.tools.InitAppServlet.init(InitAppServlet.java:21)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:616)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:396)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at mobi.allshoppings.jetty.JettyServer.startup(JettyServer.java:62)
    at mobi.allshoppings.cli.StartServer.main(StartServer.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at mobi.allshoppings.cli.CLI.main(CLI.java:100)
NestedThrowablesStackTrace:
Failed to set object CachedPC : cls=mobi.allshoppings.model.User version=null loadedFlags=[YYYYYYYYYYYYYYYYY] with id com.inodes.datanucleus.model.Key:User("admin") into Redis cache
org.datanucleus.exceptions.NucleusException: Failed to set object CachedPC : cls=mobi.allshoppings.model.User version=null loadedFlags=[YYYYYYYYYYYYYYYYY] with id com.inodes.datanucleus.model.Key:User("admin") into Redis cache
    at org.datanucleus.cache.redis.RedisLevel2Cache.put(RedisLevel2Cache.java:280)
    at org.datanucleus.ExecutionContextImpl.putObjectIntoLevel2CacheInternal(ExecutionContextImpl.java:4914)
    at org.datanucleus.ExecutionContextImpl.putObjectIntoLevel2Cache(ExecutionContextImpl.java:4741)
    at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3579)
    at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3016)
    at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1742)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:144)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:108)
    at mobi.allshoppings.bdb.tools.BasicDataBuilder.warmUp(BasicDataBuilder.java:49)
    at mobi.allshoppings.bdb.tools.InitAppServlet.init(InitAppServlet.java:21)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:616)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:396)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at mobi.allshoppings.jetty.JettyServer.startup(JettyServer.java:62)
    at mobi.allshoppings.cli.StartServer.main(StartServer.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at mobi.allshoppings.cli.CLI.main(CLI.java:100)

如堆栈所示,在序列化过程中会触发异常。我知道任何使用datanucleus存储的类都必须扩展Serializable,并且必须使用一些特殊的注释,比如@PersistenceCapable,@ NotPersistant或@EmbebedOnly

问题是,当前的生产中版本具有完全相同的配置,唯一可能破坏任何数据核配置的更改是升级本身和两个新类的声明,其中:已经注释(如在文档和其他工作类中)并且这些类在statup过程中根本不涉及,所以即使它们的配置不好,服务器也应该开始正常;但它拒绝。 persitence.xml package-mongodb.orm 似乎很好(再次,如在文档和其他工作类中)。

数据核加强过程和类路径中的依赖加入是;据我们所知,正确。

在序列化过程中得到的非序列化异常是由于(错误的?)CachePC对象(由datanucleus构建以包装实际的User对象)引起的,该对象具有一个StateManagerImpl实例的字段,并且显然是没有实现Serializable,导致异常。

注意:上面的堆栈跟踪与项目的当前配置相匹配,并且它不直接显示NoSerializableException,但在重新调试时我确认这是第一个引发的异常。当ObjectOutputStream确定StateManagerImpl不是要序列化的有效对象时,它会被引发。当前版本使用XMemcached,如果我们将此版本切换到Memcached,我们可以清楚地看到" Non-Serializable Exception"。 (我们想切换到Redis,因为原始服务器被设计成一个分布式系统;但是你会惊讶于它有多么疯狂的瓶颈)

因此;我们不知道为什么它会尝试序列化StateManagerImpl;我们认为这是最后一个datanucleus版本的错误,因此我们切换到版本5.1.0-release 但没有成功。该应用程序,Jetty服务器& servlet启动得很好,我们可以确认datanucleus成功解析datanucleus.configuration文件,我们可以获取PersistanceManager实例并读取mongo数据库。但是当它进入缓存中的写入时(这是自动完成的); Redis或XMemcached,我们总是得到一个Non-Serializable异常,因为datanucleus用不可序列化的StateManagerImpl构建一个CachedPC。

我们应该在哪里重新开始?可能有什么不对?我们应该将datanucleus切换为更受支持的数据访问层吗?

先谢谢。

更新

以下是使用Memcached而不是Redis时产生的堆栈跟踪(行为相同,再次序列化到L2 Cache时会中断)

GRAVE: exception catched
javax.jdo.JDOException: Exception thrown in persistence to xmemcached
    at org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:676)
    at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1747)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:144)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:108)
    at mobi.allshoppings.bdb.tools.BasicDataBuilder.warmUp(BasicDataBuilder.java:49)
    at mobi.allshoppings.bdb.tools.InitAppServlet.init(InitAppServlet.java:21)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:616)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:396)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at mobi.allshoppings.jetty.JettyServer.startup(JettyServer.java:62)
    at mobi.allshoppings.cli.StartServer.main(StartServer.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at mobi.allshoppings.cli.CLI.main(CLI.java:100)
NestedThrowablesStackTrace:
java.lang.IllegalArgumentException: Non-serializable object
    at net.rubyeye.xmemcached.transcoders.BaseSerializingTranscoder.serialize(BaseSerializingTranscoder.java:99)
    at net.rubyeye.xmemcached.transcoders.SerializingTranscoder.encode(SerializingTranscoder.java:211)
    at net.rubyeye.xmemcached.command.text.TextStoreCommand.encodeValue(TextStoreCommand.java:199)
    at net.rubyeye.xmemcached.command.text.TextStoreCommand.encode(TextStoreCommand.java:155)
    at net.rubyeye.xmemcached.impl.MemcachedTCPSession.wrapMessage(MemcachedTCPSession.java:189)
    at com.google.code.yanf4j.core.impl.AbstractSession.write(AbstractSession.java:383)
    at net.rubyeye.xmemcached.impl.MemcachedConnector.send(MemcachedConnector.java:556)
    at net.rubyeye.xmemcached.XMemcachedClient.sendCommand(XMemcachedClient.java:322)
    at net.rubyeye.xmemcached.XMemcachedClient.sendStoreCommand(XMemcachedClient.java:2537)
    at net.rubyeye.xmemcached.XMemcachedClient.set(XMemcachedClient.java:1369)
    at net.rubyeye.xmemcached.XMemcachedClient.set(XMemcachedClient.java:1428)
    at net.rubyeye.xmemcached.XMemcachedClient.set(XMemcachedClient.java:1415)
    at org.datanucleus.cache.xmemcached.XmemcachedLevel2Cache.put(XmemcachedLevel2Cache.java:177)
    at org.datanucleus.ExecutionContextImpl.putObjectIntoLevel2CacheInternal(ExecutionContextImpl.java:4914)
    at org.datanucleus.ExecutionContextImpl.putObjectIntoLevel2Cache(ExecutionContextImpl.java:4741)
    at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3579)
    at org.datanucleus.ExecutionContextImpl.findObject(ExecutionContextImpl.java:3016)
    at org.datanucleus.api.jdo.JDOPersistenceManager.getObjectById(JDOPersistenceManager.java:1742)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:144)
    at mobi.allshoppings.dao.spi.GenericDAOJDO.get(GenericDAOJDO.java:108)
    at mobi.allshoppings.bdb.tools.BasicDataBuilder.warmUp(BasicDataBuilder.java:49)
    at mobi.allshoppings.bdb.tools.InitAppServlet.init(InitAppServlet.java:21)
    at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:616)
    at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:396)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1342)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:505)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:163)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:387)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:354)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at mobi.allshoppings.jetty.JettyServer.startup(JettyServer.java:62)
    at mobi.allshoppings.cli.StartServer.main(StartServer.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at mobi.allshoppings.cli.CLI.main(CLI.java:100)
Caused by: java.io.NotSerializableException: org.datanucleus.state.StateManagerImpl
    - field (class "org.datanucleus.identity.IdentityReference", name: "client", type: "class java.lang.Object")
    - object (class "org.datanucleus.identity.IdentityReference", org.datanucleus.identity.IdentityReference@44fd7ba4)
    - field (class "org.datanucleus.cache.CachedPC", name: "id", type: "class java.lang.Object")
    - object (class "org.datanucleus.cache.CachedPC", CachedPC : cls=mobi.allshoppings.model.Address version=null loadedFlags=[YYYYYYYYY])
    - custom writeObject data (class "java.util.HashMap")
    - object (class "java.util.HashMap", {0=1, 1=CachedPC : cls=mobi.allshoppings.model.Address version=null loadedFlags=[YYYYYYYYY], 2=null, 3=null, 4=CachedPC : cls=mobi.allshoppings.model.ContactInfo version=null loadedFlags=[YYYYYYYYYYYY], 5=Sun Oct 29 04:57:34 CST 2017, 6=null, 7=true, 8=User("admin"), 9=null, 10=Sun Oct 29 05:03:40 CST 2017, 11=0, 12=true, 13=CachedPC : cls=mobi.allshoppings.model.UserSecurity version=null loadedFlags=[YYYYYYYYYYYYYYYYY], 14=null, 15=00000000880E0D76, 16=CachedPC : cls=mobi.allshoppings.model.tools.ViewLocation version=null loadedFlags=[Y]})
    - field (class "org.datanucleus.cache.CachedPC", name: "fieldValues", type: "interface java.util.Map")
    - root object (class "org.datanucleus.cache.CachedPC", CachedPC : cls=mobi.allshoppings.model.User version=null loadedFlags=[YYYYYYYYYYYYYYYYY])
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1182)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at java.util.HashMap.internalWriteEntries(HashMap.java:1790)
    at java.util.HashMap.writeObject(HashMap.java:1363)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1128)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at net.rubyeye.xmemcached.transcoders.BaseSerializingTranscoder.serialize(BaseSerializingTranscoder.java:94)
    ... 48 more

此外,以下是在序列化过程中抛出实际异常之前 ObjectOutputStream的debugInfoStack 的状态:

这是异常创建之前的状态:

- object (class "java.lang.StackTraceElement", java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1182))
- element of array (index: 0)
- array (class "[Ljava.lang.StackTraceElement;", size: 74)
- field (class "java.lang.Throwable", name: "stackTrace", type: "class [Ljava.lang.StackTraceElement;")
- custom writeObject data (class "java.lang.Throwable")
- root object (class "java.io.NotSerializableException", java.io.NotSerializableException: org.datanucleus.state.StateManagerImpl
- field (class "org.datanucleus.identity.IdentityReference", name: "client", type: "class java.lang.Object")
- object (class "org.datanucleus.identity.IdentityReference", org.datanucleus.identity.IdentityReference@44fd7ba4)
- field (class "org.datanucleus.cache.CachedPC", name: "id", type: "class java.lang.Object")
- object (class "org.datanucleus.cache.CachedPC", CachedPC : cls=mobi.allshoppings.model.Address version=null loadedFlags=[YYYYYYYYY])
- custom writeObject data (class "java.util.HashMap")
- object (class "java.util.HashMap", {0=1, 1=CachedPC : cls=mobi.allshoppings.model.Address version=null loadedFlags=[YYYYYYYYY], 2=null, 3=null, 4=CachedPC : cls=mobi.allshoppings.model.ContactInfo version=null loadedFlags=[YYYYYYYYYYYY], 5=Sun Oct 29 04:57:34 CST 2017, 6=null, 7=true, 8=User("admin"), 9=null, 10=Sun Oct 29 05:03:40 CST 2017, 11=0, 12=true, 13=CachedPC : cls=mobi.allshoppings.model.UserSecurity version=null loadedFlags=[YYYYYYYYYYYYYYYYY], 14=null, 15=00000000880E0D76, 16=CachedPC : cls=mobi.allshoppings.model.tools.ViewLocation version=null loadedFlags=[Y]})
- field (class "org.datanucleus.cache.CachedPC", name: "fieldValues", type: "interface java.util.Map")
- root object (class "org.datanucleus.cache.CachedPC", CachedPC : cls=mobi.allshoppings.model.User version=null loadedFlags=[YYYYYYYYYYYYYYYYY]))

此状态显示我之前没有注意到的suppressException(以及触发异常之前的最后一个状态之一):

- object (class "java.util.ArrayList", [])
- field (class "java.util.Collections$UnmodifiableCollection", name: "c", type: "interface java.util.Collection")
- object (class "java.util.Collections$UnmodifiableList", [])
- field (class "java.lang.Throwable", name: "suppressedExceptions", type: "interface java.util.List")
- custom writeObject data (class "java.lang.Throwable")
- root object (class "java.io.NotSerializableException", java.io.NotSerializableException: org.datanucleus.state.StateManagerImpl
- field (class "org.datanucleus.identity.IdentityReference", name: "client", type: "class java.lang.Object")
- object (class "org.datanucleus.identity.IdentityReference", org.datanucleus.identity.IdentityReference@44fd7ba4)
- field (class "org.datanucleus.cache.CachedPC", name: "id", type: "class java.lang.Object")
- object (class "org.datanucleus.cache.CachedPC", CachedPC : cls=mobi.allshoppings.model.Address version=null loadedFlags=[YYYYYYYYY])
- custom writeObject data (class "java.util.HashMap")
- object (class "java.util.HashMap", {0=1, 1=CachedPC : cls=mobi.allshoppings.model.Address version=null loadedFlags=[YYYYYYYYY], 2=null, 3=null, 4=CachedPC : cls=mobi.allshoppings.model.ContactInfo version=null loadedFlags=[YYYYYYYYYYYY], 5=Sun Oct 29 04:57:34 CST 2017, 6=null, 7=true, 8=User("admin"), 9=null, 10=Sun Oct 29 05:03:40 CST 2017, 11=0, 12=true, 13=CachedPC : cls=mobi.allshoppings.model.UserSecurity version=null loadedFlags=[YYYYYYYYYYYYYYYYY], 14=null, 15=00000000880E0D76, 16=CachedPC : cls=mobi.allshoppings.model.tools.ViewLocation version=null loadedFlags=[Y]})
- field (class "org.datanucleus.cache.CachedPC", name: "fieldValues", type: "interface java.util.Map")
- root object (class "org.datanucleus.cache.CachedPC", CachedPC : cls=mobi.allshoppings.model.User version=null loadedFlags=[YYYYYYYYYYYYYYYYY]))

将Lists作为属性的唯一类是User类的属性,它具有以下声明:

@PersistenceCapable(detachable="true")
@EmbeddedOnly
public class UserSecurity implements Serializable {

我不会在缓存过程中看到它被调用,只有在mongodb阅读期间。再说一次:mongodb的讲座工作得很好,但是作为datanucleus tryies缓存刚刚被引用的对象;它失败。所以,我不知道那个无法修改的名单即将来临。

1 个答案:

答案 0 :(得分:0)

所以,也许我有点太咸了;但实际上我们的问题实际上是由Datanucleus bug造成的:https://github.com/datanucleus/datanucleus-core/issues/283

文档说嵌入对象不应该有ID,因为它们直接被带有ID的容器对象所喜欢(在"相同的表"方案下)http://www.datanucleus.org/products/datanucleus/jdo/mapping.html#embedded_pc 但是我们的嵌入式对象被赋予了一个不应该存在的IdentityReference。

我注意到在对序列化嵌入对象时,StateManagerImpl是异常的原因,但我没有太多关注导致StateManagerImpl序列化的IdentityReference对象;导致缓存L2写入错误。这就是bug的全部内容。

因此,解决方案是克隆datanucleus-core项目,在本地构建和安装最新版本,并重新构建我们的项目,将datanuclues-core依赖项更改为本地文件。它工作得很好。

在深入研究datanucleus及其代码本身的文档之后,我更确信datanucleus实际上是一个非常好的数据存储抽象,我们将它保留在我们的项目中(但我仍然相信支持和错误消息含糊不清)