# S01 — Mapper construction and immutability Guide: (Steps 2 and 3) [`before/S01MapperConstruction.java`](../jackson2-before/src/main/java/com/ankurm/migration/before/S01MapperConstruction.java) · [`after/S01MapperConstruction.java`](../jackson3-after/src/main/java/com/ankurm/migration/after/S01MapperConstruction.java) ## The guide's "after" snippet does not compile ```java JsonMapper mapper = JsonMapper.builder() .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // no such constant .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .serializationInclusion(JsonInclude.Include.NON_NULL) // no such method .build(); ``` Two of those four lines are invalid against Jackson 3.2.1: - `SerializationFeature.WRITE_DATES_AS_TIMESTAMPS` does not exist. The flag moved to `tools.jackson.databind.cfg.DateTimeFeature` and now defaults to off, so ISO-8601 output needs no configuration and there is nothing to disable. - `JsonMapper.Builder.serializationInclusion(...)` does not exist. The real API is `changeDefaultPropertyInclusion(UnaryOperator)`. The third line is valid but redundant — `FAIL_ON_UNKNOWN_PROPERTIES` already defaults to `false` in Jackson 3. ## Output **Jackson 2 — `jackson2-before`** ``` output : {"id":1,"travelDate":"2026-09-15","seatPreference":"aisle"} after mutation : { "id" : 1, "travelDate" : "2026-09-15", "seatPreference" : "aisle" } mutation stuck : true set*() mutators : 40 ``` **Jackson 3 — `jackson3-after`** ``` output : {"id":1,"travelDate":"2026-09-15","seatPreference":"aisle"} forked indented : { "id" : 1, "travelDate" : "2026-09-15", "seatPreference" : "aisle" } original intact : false set*() mutators : 0 <- mutation is impossible, not merely discouraged ``` Both produce the same JSON, which is the reassuring part. The interesting lines are the last two of each. In Jackson 2 the mapper stays mutable forever. `mapper.enable(INDENT_OUTPUT)` after the mapper has been injected into a dozen components takes effect for all of them — `mutation stuck : true`. Forty `set*` methods are available to do it with. In Jackson 3 there are zero. To vary configuration you fork: `rebuild()` returns a builder seeded from the existing mapper, and the original is untouched (`original intact : false`).