Model Dynamic JSON Keys with Map<String, Object>

When JSON contains arbitrary keys (feature flags, metadata maps, dynamic settings), model the field as Map<String, Object> instead of generating a class.

Special Cases

Detailed Explanation

When a POJO Is the Wrong Choice

Most JSON has a fixed schema: keys are known up front and each key has a documented meaning. But some JSON uses keys as data — feature flag names, user-defined metadata, or arbitrary tags. For those cases, modeling each key as a Java field is impossible. Use Map<String, Object> instead.

Example JSON with Dynamic Keys

{
  "user_id": 42,
  "feature_flags": {
    "new_dashboard": true,
    "beta_search": false,
    "ai_assistant": true
  }
}

Recommended Java Model

package com.example.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;

public class UserContext {
    @JsonProperty("user_id")
    private Integer userId;

    @JsonProperty("feature_flags")
    private Map<String, Boolean> featureFlags;

    // accessors
}

When the values share a type (here, all booleans), use Map<String, Boolean> for type safety. When the values are heterogeneous, fall back to Map<String, Object>.

Why the Generator Cannot Detect This Automatically

The generator sees a JSON object and produces a class. It has no way to know whether the keys are part of the schema (firstName, lastName) or part of the data (new_dashboard, beta_search). After generation, replace the auto-created class with a Map field if your domain knowledge tells you the keys are dynamic.

Heuristics for Spotting "Map-shaped" JSON

  • Keys look like identifiers users would create (UUIDs, slugs, free text)
  • Values are all the same primitive type
  • The number of keys varies between documents
  • Documentation describes the field as "metadata", "tags", or "custom fields"

Jackson Behavior

Jackson handles Map<String, T> natively — no annotations are required beyond the field type. The deserializer reads each JSON key as a Map entry and decodes the value into T.

Mixed Schema and Map Together

{
  "id": 1,
  "name": "Acme",
  "tags": ["startup", "fintech"],
  "metadata": {
    "founded_year": 2018,
    "headcount": 42,
    "location": "Berlin"
  }
}
public class Company {
    private Integer id;
    private String name;
    private List<String> tags;
    private Map<String, Object> metadata; // unknown shape
}

This pattern is common: a known schema plus an open-ended metadata bag for extension fields.

Use Case

Feature flag systems, user preferences, custom attributes on CRM contacts, and webhook event payloads with extensible metadata all benefit from a Map<String, Object> field rather than a generated class.

Try It — JSON to Java

Open full tool