# 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`).