2

我正在使用 Gemfire Spring 放置/查找 pojo 对象

@Autowired
GemfireTemplate responseTemplate;
....
HTTPAudit audit = new HTTPAudit(sessionId,response);   
responseTemplate.put("Detail", audit);
System.out.println("Get caching...");
SelectResults<HTTPAudit> result = responseTemplate.find("SELECT * from /HTTPAudit WHERE sessionId= $1", sessionId);

HTTPAudit 对象实现了 Serializable 接口。

该实体已成功保存在 Gemfire 中,但在尝试反序列化时会引发异常。错误消息是“com.gemstone.gemfire.SerializationException:尝试反序列化缓存值时抛出了 ClassNotFoundException。”

4

1 回答 1

2

有关您的配置的详细信息在此处不完整。有许多可能的情况会发生这种情况。一种更可能的情况是,上面的代码片段可能是一个客户端缓存,其中 /HTTPAudit 是某个对等服务器区域的代理客户端区域(数据策略不清楚,但如果这是一个正在使用的客户端/服务器拓扑,则不那么重要)。

因为您的 HTTPAudit 实现了 java.io.Serializable,GemFire 将使用 Java 序列化通过网络发送对象。

然后,GemFire 会将对象存储在它获得的“形式”中(在本例中为序列化)。

接下来,您继续运行 OQL 语句 (Query) 并继续访问对象 (sessionId) 上的字段。因为 GemFire 不能以“Java 序列化”形式访问数据,所以它必须反序列化该值以检查它的查询谓词。

在这种情况下,我猜您的“GemFire Server”节点在 CLASSPATH 上没有它需要的 HTTPAudit 类。

如果您想避免在发出上述 OQL 时对 GemFire 服务器上的 HTTPAudit 对象进行反序列化,那么您应该切换到 PDX 序列化(http://gemfire.docs.pivotal.io/latest/userguide/developing /data_serialization/gemfire_pdx_serialization.html ),并将服务器的配置 'read-serailized' 属性设置为 true。

但是,您应该小心,因为并非对对象的所有 OQL 操作都必须将对象保持为序列化形式,即使在使用 PDX 时也是如此。

例如,一个 OQL 查询类似于...

SELECT audit.toString() FROM /HTTPAudit audit WHERE ...

甚至会导致在查询执行期间反序列化 PDX 序列化对象。

并不是说调用 toString() 是好的做法(只是为了说明一点),但是某些对象操作可能会导致 GemFire 在处理过程中反序列化一个值以执行 OQL 语句中的对象操作,即使以 PDX 序列化形式存储也是如此,因此要求该类位于服务器的 CLASSPATH 上。所以,要小心。

但是,在您的情况下,问题是由于您使用效率较低但更标准的 Java 序列化来存储和访问您的对象而引起的。与 PDX 序列化不同,没有“类型元数据”使 GemFire 能够以序列化形式访问对象上的数据,而无需先“反序列化”它。使用 Java 序列化,GemFire 必须反序列化对象以访问它的信息。

希望这可以帮助。

于 2014-08-14T00:34:19.873 回答