DEV Community

Cover image for JSON Schema to Java: A Better Object Model
Yu Han
Yu Han

Posted on

JSON Schema to Java: A Better Object Model

Start with a simple schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Order",
  "type": "object",
  "required": ["id", "amount", "customer"],
  "properties": {
    "id": { "type": "string" },
    "amount": { "type": "number" },
    "customer": {
      "type": "object",
      "properties": {
        "email": { "type": "string" }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Because additionalProperties defaults to true, many JSON Schema-to-Java generators produce a POJO like this:

public class Order {
    private String id;
    private BigDecimal amount;
    private Customer customer;
    private Map<String, Object> additionalProperties = new LinkedHashMap<>();

    // normal getters and setters...

    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }
}
Enter fullscreen mode Exit fullscreen mode

It works.

But it is ugly.

additionalProperties is a JSON Schema concept. Exposing it as part of every generated Java model leaks schema internals into your application API.

Generated code is still code. Developers read it, debug it, autocomplete it, and often build long-lived systems around it. So the generated model should look like Java, not like a schema engine dump.

A cleaner approach

SJF4J takes a different route.

Instead of forcing dynamic JSON properties into a public additionalProperties map, SJF4J can generate JOJO-style models: Java objects that extend JsonObject.

public class Order extends JsonObject {
    private String id;
    private BigDecimal amount;
    private Customer customer;

    // normal getters and setters...

    // no generated additionalProperties map
}
Enter fullscreen mode Exit fullscreen mode

No getAdditionalProperties().

The model stays clean, while still supporting JSON-style dynamic properties when the schema allows them. The object model carries the dynamic behavior; the generated Java API does not have to expose a schema keyword as a public map.

If the schema says additionalProperties: false, SJF4J can also generate stricter POJO-style models or disable dynamic reads depending on the selected strategy.

Online generator

You can try it here:

👉 https://sjf4j.org/generator

The generator supports options like:

  • JOJO or POJO modeling
  • Lombok or explicit getters/setters
  • validation annotations
  • enum/date/time mapping
  • path-only models
  • generated JSON Path accessors

So a nested schema field can become a convenient Java method instead of boilerplate object walking.

Direct schema validation on Java objects

The other important part: SJF4J validates Java object graphs directly against JSON Schema.

Typical validation often looks like this:

Java object -> JSON string -> JSON tree -> schema validation
Enter fullscreen mode Exit fullscreen mode

SJF4J avoids that extra round trip.

A schema can be compiled into a SchemaPlan and applied directly to a Java object, including a plain POJO:

SchemaPlan plan = JsonSchema.fromJson(schemaText).createPlan();
ValidationResult result = plan.validate(order);
Enter fullscreen mode Exit fullscreen mode

If you want to bind the schema to the generated Java model, you can declare the schema reference on the class:

@ValidJsonSchema(ref = "Order.json")
public class Order extends JsonObject {
    // generated fields
}
Enter fullscreen mode Exit fullscreen mode

The schema can live as a normal classpath resource, for example:

src/main/resources/json-schemas/Order.json
Enter fullscreen mode Exit fullscreen mode

Then validation becomes even more direct:

SchemaValidator validator = new SchemaValidator();
ValidationResult result = validator.validate(order);
Enter fullscreen mode Exit fullscreen mode

The schema lookup and compiled validation plan can be cached and reused, which makes this model suitable for hot paths as well.

No serialization.

No parsing back into a JSON tree.

Just JSON Schema semantics applied to the Java object graph.

That is simpler and faster.

SJF4J supports JSON Schema Draft 2020-12 / 2019-09 / draft-07 and performs well in public benchmarks such as Creek Service:

👉 https://www.creekservice.org/json-schema-validation-comparison/

The bigger picture

JSON Schema should be more than a document-bound validation format.

In Java applications, the data often already exists as objects. The interesting question is whether JSON semantics can operate on those objects directly.

SJF4J's answer is yes:

  • generate Java-friendly models from JSON Schema
  • keep dynamic object behavior available when the schema allows it
  • validate native Java object graphs without a JSON round trip
  • use the same object graph with JSON Path, JSON Pointer, JSON Patch, and mapping APIs

That is the larger model: schema, validation, navigation, and transformation working on the same in-memory Java structure.

Try it:

Curious what others think:

Should JSON Schema in Java stay tied to serialized JSON documents, or should JSON semantics work directly on native Java object graphs?

Top comments (0)