This error is occurred while using JsonObject(GSON Library) in cache value if I used String instead of JsonObject then operation perform successfully.
Error which I have get while inserting data in cache:
javax.cache.CacheException: class org.apache.ignite.transactions.TransactionRollbackException: Transaction has been rolled back: 9557fcfb061-00000000-078a-a446-0000-000000000001
at org.apache.ignite.internal.processors.cache.GridCacheUtils.convertToCacheException(GridCacheUtils.java:1287)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.cacheException(IgniteCacheProxyImpl.java:1648)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.put(IgniteCacheProxyImpl.java:1008)
at org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.put(GatewayProtectedCacheProxy.java:872)
at com.clouzer.databaseoperation.DataBaseOperation.getAllUSerGson(DataBaseOperation.java:527)
at com.mstorm.ignition.gson.LoginCacheOperation.createLoginCache(LoginCacheOperation.java:38)
at com.mstorm.ignition.gson.IgniteCacheCreator.createCaches(IgniteCacheCreator.java:30)
at com.mstorm.ignition.gson.IgniteServer.main(IgniteServer.java:102)
Caused by: class org.apache.ignite.transactions.TransactionRollbackException: Transaction has been rolled back: 9557fcfb061-00000000-078a-a446-0000-000000000001
at org.apache.ignite.internal.util.IgniteUtils$11.apply(IgniteUtils.java:860)
at org.apache.ignite.internal.util.IgniteUtils$11.apply(IgniteUtils.java:858)
... 8 more
Caused by: class org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException: Transaction has been rolled back: 9557fcfb061-00000000-078a-a446-0000-000000000001
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.syncOp(GridCacheAdapter.java:4054)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.put0(GridCacheAdapter.java:2340)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.put(GridCacheAdapter.java:2321)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.put(GridCacheAdapter.java:2298)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.put(IgniteCacheProxyImpl.java:1005)
... 5 more
Caused by: class org.apache.ignite.IgniteCheckedException: Can not set final com.google.gson.internal.LinkedTreeMap field com.google.gson.JsonObject.members to java.util.LinkedHashMap
at org.apache.ignite.internal.util.IgniteUtils.cast(IgniteUtils.java:7252)
at org.apache.ignite.internal.util.future.GridFutureAdapter.resolve(GridFutureAdapter.java:259)
at org.apache.ignite.internal.util.future.GridFutureAdapter.get0(GridFutureAdapter.java:171)
at org.apache.ignite.internal.util.future.GridFutureAdapter.get(GridFutureAdapter.java:140)
at org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal$10.applyx(GridNearTxLocal.java:2396)
at org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal$10.applyx(GridNearTxLocal.java:2392)
at org.apache.ignite.internal.util.lang.IgniteClosureX.apply(IgniteClosureX.java:38)
at org.apache.ignite.internal.util.future.GridFutureChainListener.applyCallback(GridFutureChainListener.java:78)
at org.apache.ignite.internal.util.future.GridFutureChainListener.apply(GridFutureChainListener.java:70)
at org.apache.ignite.internal.util.future.GridFutureChainListener.apply(GridFutureChainListener.java:30)
at org.apache.ignite.internal.util.future.GridFutureAdapter.notifyListener(GridFutureAdapter.java:383)
at org.apache.ignite.internal.util.future.GridFutureAdapter.listen(GridFutureAdapter.java:353)
at org.apache.ignite.internal.util.future.GridFutureAdapter$ChainFuture.<init>(GridFutureAdapter.java:572)
at org.apache.ignite.internal.util.future.GridFutureAdapter.chain(GridFutureAdapter.java:358)
at org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal.optimisticPutFuture(GridNearTxLocal.java:2391)
at org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal.putAsync0(GridNearTxLocal.java:622)
at org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal.putAsync(GridNearTxLocal.java:385)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter$22.op(GridCacheAdapter.java:2342)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter$22.op(GridCacheAdapter.java:2340)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.syncOp(GridCacheAdapter.java:4040)
... 9 more
Cache Configuration:
CacheConfiguration<String, JsonObject> cacheConfig = new CacheConfiguration<>();
cacheConfig.setName("CACHE_NAME");
cacheConfig.setReadThrough(true);
cacheConfig.setBackups(2);
cacheConfig.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
cacheConfig.setWriteThrough(true);
cacheConfig.setCacheStoreFactory(FactoryBuilder.factoryOf(ObjectLoader.class));
IgniteCache<String, JsonObject> cache = ignite.getOrCreateCache(cacheConfig);
Operations:
1.create JsonObject (use GSON library)
2.set cache loader to the given cache which used for persistent store
3.insert data into the cache from ignite client-side
4.observe the issue
The problem is that JsonObject
has members
field of type LinkedTreeMap
, and Ignite BinaryMarshaller
, which is default one, deserializes it into a LinkedHashMap
for some reason.
To avoid it you can use a different marshaller, for example, OptimizedMarshaller
.
UPD:
Turns out, if you configure OptimizedMarshaller
, then only puts and gets from cache will work fine. But if you try to get(...)
some field of the deserialized representation of JsonObject
, for example, then JVM will crash.
The reason is that LinkedTreeMap
has the following writeReplace()
method:
private Object writeReplace() throws ObjectStreamException {
return new LinkedHashMap(this);
}
So, if you serialize it, and after that deserialize, then you will get an instance of LinkedHashMap
instead of LinkedTreeMap
. So, BinaryMarshaller
is doing nothing wrong.
Summary:
Looks like you shouldn't put JsonObject
s into cache. It doesn't implement Serializable
, so the authors didn't think about serializing it. I think, you will have to replace JsonObject
with JSON strings.