{"record":{"id":"704e50116cade4d9","repo":"heibaiying/BigData-Notes","slug":"cannot-process-such-data-type-for-count-datatyp-704e50","errorCode":null,"errorMessage":"Cannot process such data type for Count: ${dataType}","messagePattern":"Cannot process such data type for Count: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"notes/Storm集成Redis详解.md","lineNumber":589,"sourceCode":"        super(config);\n        this.storeMapper = storeMapper;\n        RedisDataTypeDescription dataTypeDescription = storeMapper.getDataTypeDescription();\n        this.dataType = dataTypeDescription.getDataType();\n        this.additionalKey = dataTypeDescription.getAdditionalKey();\n    }\n\n    @Override\n    protected void process(Tuple tuple) {\n        String key = storeMapper.getKeyFromTuple(tuple);\n        String value = storeMapper.getValueFromTuple(tuple);\n\n        JedisCommands jedisCommand = null;\n        try {\n            jedisCommand = getInstance();\n            if (dataType == RedisDataTypeDescription.RedisDataType.HASH) {\n                jedisCommand.hincrBy(additionalKey, key, Long.valueOf(value));\n            } else {\n                throw new IllegalArgumentException(\"Cannot process such data type for Count: \" + dataType);\n            }\n\n            collector.ack(tuple);\n        } catch (Exception e) {\n            this.collector.reportError(e);\n            this.collector.fail(tuple);\n        } finally {\n            returnInstance(jedisCommand);\n        }\n    }\n\n    @Override\n    public void declareOutputFields(OutputFieldsDeclarer declarer) {\n\n    }\n}\n```\n","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/heibaiying/BigData-Notes/blob/3898939aca387c25b3eb4e51ef49dfccca8543ed/notes/Storm集成Redis详解.md#L571-L607","documentation":"This is the same misconfiguration as in the Java source RedisCountStoreBolt: the counting bolt only implements Redis HINCRBY over a hash, so when the RedisStoreMapper's RedisDataTypeDescription declares anything other than HASH, process() throws this IllegalArgumentException, reports the error to the topology, and fails the tuple. The snippet here appears in the project's Chinese-language notes (Storm集成Redis详解.md) demonstrating a hand-written count bolt, so hitting it usually means the demo mapper was configured for a non-hash type.","triggerScenarios":"Following the notes' example but building the RedisStoreMapper with RedisDataTypeDescription.RedisDataType.STRING / SORTED_SET / HYPER_LOG_LOG / GEO instead of HASH; or reusing a mapper written for the notes' RedisStoreBolt section (which supports those types) inside the RedisCountStoreBolt section. The throw happens on the first processed tuple, inside the else branch after the HASH check fails.","commonSituations":"Working through this repo's tutorial and copy-pasting a mapper from the store-bolt section into the count-bolt topology; adapting the demo to a different Redis structure without editing the count bolt's process(); version drift between the notes' code and the actual storm-redis API constants used in the mapper.","solutions":["In the mapper used with the count bolt, return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, \"WORD_COUNT\") (any descriptive additionalKey works as the hash's key).","Keep two distinct mapper classes: one for RedisStoreBolt (multi-type) and one for RedisCountStoreBolt (HASH-only) so the wrong one cannot be wired in silently.","Add a constructor-time check in the custom bolt: if (dataTypeDescription.getDataType() != HASH) throw ... so the topology fails at submission, not on the first tuple.","If a non-hash counter is required, switch to RedisStoreBolt with SORTED_SET and use ZINCRBY semantics via a custom bolt, not this HINCRBY-only implementation."],"exampleFix":"// before\npublic class MyCountMapper implements RedisStoreMapper {\n    public RedisDataTypeDescription getDataTypeDescription() {\n        return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.STRING, null);\n    }\n}\n\n// after\npublic class MyCountMapper implements RedisStoreMapper {\n    public RedisDataTypeDescription getDataTypeDescription() {\n        return new RedisDataTypeDescription(RedisDataTypeDescription.RedisDataType.HASH, \"WORD_COUNT\");\n    }\n}","handlingStrategy":"validation","validationCode":"RedisDataTypeDescription d = storeMapper.getDataTypeDescription();\nif (d == null || d.getDataType() != RedisDataTypeDescription.RedisDataType.HASH) {\n    throw new IllegalArgumentException(\n        \"RedisCountStoreBolt requires HASH, got: \" + (d == null ? \"null\" : d.getDataType()));\n}","typeGuard":"boolean isUsableForCountBolt(org.apache.storm.redis.common.mapper.RedisStoreMapper mapper) {\n    RedisDataTypeDescription d = mapper.getDataTypeDescription();\n    return d != null\n        && d.getDataType() == org.apache.storm.redis.common.mapper.RedisDataTypeDescription.RedisDataType.HASH;\n}","tryCatchPattern":"// Fail fast at topology build time instead of relying on the per-tuple catch:\nif (!isUsableForCountBolt(storeMapper)) {\n    throw new IllegalStateException(\"Use a HASH-typed mapper with RedisCountStoreBolt; \"\n        + \"got: \" + storeMapper.getDataTypeDescription().getDataType());\n}","preventionTips":["When following tutorial code, keep the mapper class paired with the bolt section it belongs to; name them accordingly (WordCountStoreMapper for the count bolt).","Assert HASH in the bolt constructor or prepare() so a wrong mapper fails the topology at launch.","Cover the bolt with a one-tuple LocalCluster integration test; this error only appears once real tuples flow.","Document on the mapper class which bolts it may be used with."],"tags":["storm","redis","jedis","illegalargumentexception","configuration","documentation"],"backgroundTag":null,"analyzedSha":"3898939aca387c25b3eb4e51ef49dfccca8543ed","analyzedAt":"2026-08-14T15:36:11.245Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}