当键为 BinaryObject 且没有 类 可用于键类型时,Ignite readThrough 出现问题

Problem with Ignite readThrough when key is BinaryObject and no classes available for key type

我有一个用例,我的 Ignite 缓存 key/value 没有对应的 Java class,我使用 BinaryObject 作为键和值类型。下面的代码工作正常(没有任何通读)。

CacheConfiguration cfg = new CacheConfiguration("cache1");
IgniteCache<BinaryObject, BinaryObject> cache1 = ignite.getOrCreateCache(cfg).withKeepBinary();
cache1.put(createBOKey("mykey", "k1"), createBOVal());
cache1.put(createBOKey("mykey", "k2"), createBOVal());
cache1.put(createBOKey("mykey", "k3"), createBOVal());
Object v1 = cache1.get(createBOKey("mykey", "k1"));
System.out.println("**** cache1 key " + v1); // shows value
Object v2 = cache1.get(createBOKey("mykey", "k10"));
System.out.println("**** cache1 key " + v2); // show null

BinaryObject createBOKey(String k, String v) {
    BinaryObjectBuilder builder = ignite.binary().builder("key-type1");
    builder.setField(k, v);
    return builder.build();
}
BinaryObject createBOVal() {
    BinaryObjectBuilder builder = ignite.binary().builder("value-type1");
    builder.setField(fieldName("cache1", "f1"), "hello");
    builder.setField(fieldName("cache1", "f2"), 10.75);
    return builder.build();
}

现在,一旦我为此缓存启用 readThrough,它就会开始因缓存未命中而失败。

cfg.setReadThrough(true);
cfg.setCacheLoaderFactory(new Factory<CacheLoader<BinaryObject, BinaryObject>>() {
    @Override
    public CacheLoader<BinaryObject, BinaryObject> create() {
        return new CacheLoader<BinaryObject, BinaryObject>() {
            @Override
            public BinaryObject load(BinaryObject obj) throws CacheLoaderException {
                System.out.println("**** Loading from backingstore " + obj);
                return null;
            }
            @Override
            public Map<BinaryObject, BinaryObject> loadAll(Iterable<? extends BinaryObject> arg0) throws CacheLoaderException {
                return null;
            }
        };
    }
});

在缓存未命中时,它会抛出以下异常,甚至不会到达 cacheloader.load()。

Exception in thread "main" javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: key-type1
    at org.apache.ignite.internal.processors.cache.GridCacheUtils.convertToCacheException(GridCacheUtils.java:1317)
    at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.cacheException(IgniteCacheProxyImpl.java:2066)
    at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.get(IgniteCacheProxyImpl.java:1093)
    at org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.get(GatewayProtectedCacheProxy.java:676)
    at com.basit.bo.btree.TestBinaryTreeMapKey.main(TestBinaryTreeMapKey.java:74)
Caused by: class org.apache.ignite.IgniteCheckedException: key-type1
    at org.apache.ignite.internal.util.IgniteUtils.cast(IgniteUtils.java:7507)
    at org.apache.ignite.internal.processors.closure.GridClosureProcessor.body(GridClosureProcessor.java:975)
    at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:120)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: class org.apache.ignite.binary.BinaryInvalidTypeException: key-type1
    at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:762)
    at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1757)
    at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1716)
    at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:792)
    at org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:142)
    at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinary(CacheObjectUtils.java:176)
    at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinaryIfNeeded(CacheObjectUtils.java:67)
    at org.apache.ignite.internal.processors.cache.CacheObjectContext.unwrapBinaryIfNeeded(CacheObjectContext.java:136)
    at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1808)
    at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1796)
    at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadFromStore(GridCacheStoreManagerAdapter.java:314)
    at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.load(GridCacheStoreManagerAdapter.java:293)
    at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAllFromStore(GridCacheStoreManagerAdapter.java:434)
    at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAll(GridCacheStoreManagerAdapter.java:400)
    at org.apache.ignite.internal.processors.cache.GridCacheAdapter.call(GridCacheAdapter.java:2225)
    at org.apache.ignite.internal.processors.cache.GridCacheAdapter.call(GridCacheAdapter.java:2223)
    at org.apache.ignite.internal.processors.cache.GridCacheContext.call(GridCacheContext.java:1479)
    at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:7005)
    at org.apache.ignite.internal.processors.closure.GridClosureProcessor.body(GridClosureProcessor.java:967)
    ... 4 more
Caused by: java.lang.ClassNotFoundException: key-type1
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:398)
    at org.apache.ignite.internal.util.IgniteUtils.forName(IgniteUtils.java:8828)
    at org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:324)
    at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:753)
    ... 22 more

您还应该将 storeKeepBinary 设置为 true