public record AddressDTO(String street, String city) {}
public record UserDTO(String name, AddressDTO address) {}
@RestController
public class UserController {
@GetMapping("/user")
public UserDTO getUser() {
AddressDTO address = new AddressDTO("123 Main St", "Springfield");
return new UserDTO("John Doe", address);
}
}The nested DTO AddressDTO is serialized as a JSON object inside the address field. So the full nested structure appears in the JSON response.
userDTO.address.city after calling mapToUserDTO()?public record AddressDTO(String street, String city) {}
public record UserDTO(String name, AddressDTO address) {}
public UserDTO mapToUserDTO() {
AddressDTO address = new AddressDTO("456 Elm St", "Metropolis");
return new UserDTO("Alice", address);
}The address field inside UserDTO holds an AddressDTO with city "Metropolis".
UserDTO with a nested AddressDTO?Option A correctly defines both DTOs with all needed fields. Other options miss fields or mismatch types.
UserDTO but the JSON response fails. What is the cause?public class AddressDTO { private String street; private String city; // no getters or setters } public class UserDTO { private String name; private AddressDTO address; // getters and setters only for name } @RestController public class UserController { @GetMapping("/user") public UserDTO getUser() { AddressDTO address = new AddressDTO(); address.street = "789 Oak St"; address.city = "Gotham"; UserDTO user = new UserDTO(); user.setName("Bruce"); user.setAddress(address); return user; } }
Jackson uses getters to serialize fields. Without getters in AddressDTO, it cannot read the nested fields, causing serialization failure.
By default, Jackson (used by Spring Boot) throws a StackOverflowError on circular references. Using annotations like @JsonManagedReference and @JsonBackReference helps break the cycle during serialization.
