W've just upgraded our application from Hazelcast 3.8.0 to 3.10.1.
We am getting an error message "key cannot be of type Data!" when accessing data in Hazelcast.
java.lang.IllegalArgumentException: key cannot be of type Data!
at com.hazelcast.util.Preconditions.checkNotInstanceOf(Preconditions.java:300)
at com.hazelcast.internal.nearcache.impl.DefaultNearCache.checkKeyFormat(DefaultNearCache.java:226)
at com.hazelcast.internal.nearcache.impl.DefaultNearCache.get(DefaultNearCache.java:114)
at com.hazelcast.map.impl.tx.TransactionalMapProxySupport.getCachedValue(TransactionalMapProxySupport.java:183)
at com.hazelcast.map.impl.tx.TransactionalMapProxySupport.getInternal(TransactionalMapProxySupport.java:132)
at com.hazelcast.map.impl.tx.TransactionalMapProxy.get(TransactionalMapProxy.java:110)
at com.hazelcast.client.impl.protocol.task.transactionalmap.TransactionalMapGetMessageTask.innerCall(TransactionalMapGetMessageTask.java:43)
at com.hazelcast.client.impl.protocol.task.AbstractTransactionalMessageTask.call(AbstractTransactionalMessageTask.java:34)
at com.hazelcast.client.impl.protocol.task.AbstractCallableMessageTask.processMessage(AbstractCallableMessageTask.java:35)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.initializeAndProcessMessage(AbstractMessageTask.java:130)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.run(AbstractMessageTask.java:110)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:64)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:80)
at ------ submitted from ------.(Unknown Source)
I am 100% sure that the "key" We're using is a String. The code snippet looks like this:
String key = getKey(blah, blah);
TransactionContext context = client.newTransactionContext();
context.beginTransaction();
TransactionalMap<String, AppPrefs> dataMap = context.getMap(MAP_NAME);
try {
prefs = dataMap.get(key);
context.commitTransaction();
} catch (Throwable t) {
LOGGER.error("Error getting AppPrefs.", t);
context.rollbackTransaction();
}
The line of code throwing the error is:
prefs = dataMap.get(key);
There is nothing between the line of code that sets the String
String key = getKey(blah, blah);
and the line that blows :(
Following the source code through, the TransactionalMapProxySupport's method "toNearCacheKeyWithStrategy" has this logic:
final Object toNearCacheKeyWithStrategy(Object key) {
if (!nearCacheEnabled) {
return key;
}
return serializeKeys ? ss.toData(key, partitionStrategy) : key;
}
The "DefaultNearCache" object then does a
private void checkKeyFormat(K key) {
if (!serializeKeys) {
checkNotInstanceOf(Data.class, key, "key cannot be of type Data!");
}
}
So it looks like the property of "TransactionalMapProxySupport" called "serializeKeyes" must have been FALSE but the same-named property in "DefaultNearCache"must have been true :(
The history of "DefaultNearCache" in git shows that the code was changed a year ago with the message: "Changed serialize-keys default for Near Cache from true to false"
Is there some configuration I should be setting?
The config I have for the map is simply:
<near-cache name="AppPrefsCache">
<!-- Cache locally for 10 mins -->
<max-idle-seconds>600</max-idle-seconds>
</near-cache>
Ah! It appears that I can add a " serialize-keys" tag of (true|false) to this xml and set the value.
It appears that different bits of the Hazelcast codebase are assuming a different default value for "serialize-keys". Either it should be a mandatory element in the config or the default should be the same everywhere, yes?
The mentioned behavior is really a bug in Hazelcast. I've created a new GitHub issue for it, so we can handle it properly - hazelcast/hazelcast#13371 .
The workaround for versions affected by the bug is to set serialize-keys
to true
in the near-cache
configuration. The false
value won't help here.
Config config = new Config();
config.getMapConfig(testName)
.setNearCacheConfig(new NearCacheConfig().setSerializeKeys(true));
Thanks for the report and great investigation, Peter.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.