Casting Maps into Complex Objects in Java
In Java, there is often a need to convert a Map to a complex object (POJO – Plain Old Java Object). This can arise in various scenarios, such as when working with JSON data or other forms of structured data. Direct casting from a Map to a POJO doesn’t work due to type incompatibility and the structure of data representation.
However, libraries like Jackson and Gson provide mechanisms to facilitate this conversion. This article will explore various methods to achieve this conversion using these libraries.
1. Understanding the Challenge: Why Direct Casting Fails
Direct casting fails because a Map is a collection of key-value pairs, where the keys are typically strings and the values are objects. A POJO, on the other hand, has a defined structure with fields of specific types. Casting directly from a Map to a POJO doesn’t provide the mechanism to match the keys of the Map to the fields of the POJO and doesn’t account for data type conversions.
public class MapToPojoWithJackson {
// Creating the employee map
private static final Map<String, Object> employeemap = Map.of(
"department", new Department("Engineering", "Building A"),
"name", "Omos",
"projects", List.of(
new Project("Project A", "Developing new feature"),
new Project("Paris", "Bug fixing and maintenance")
)
);
public static void main(String[] args) {
// Attempting direct cast (will cause an error)
Employee employee = (Employee) employeemap;
System.out.println(employee);
}
}
In the above code, if we attempt to cast the Map<String, Object> directly to an Employee object will result in a ClassCastException. The output will look something like this:
Exception in thread "main" java.lang.ClassCastException:
This is not possible because a Map is fundamentally different from a POJO in terms of how data is structured and accessed. Java does not provide any built-in mechanism to automatically convert a Map to a POJO. This conversion typically requires a library like Jackson or Gson to handle the deserialization process.
2. Defining the Domain Class
Here’s an example of three domain classes: Employee, Department, and Project, demonstrating a scenario where an Employee belongs to one Department and can work on multiple Project objects.
Employee.java
public class Employee {
private String name;
private Department department;
private List<Project> projects;
// Constructors, getters, and setters
}
Department.java
public class Department {
private String name;
private String location;
// Constructors, getters, and setters
}
Project.java
public class Project {
private String name;
private String description;
// Constructors, getters, and setters
}
3. Cast Map to POJO with Jackson
Jackson is a popular library for processing JSON in Java. It can be used to convert a Map to a POJO using its ObjectMapper class.
Add Jackson Dependency
pom.xml
Add the following dependency to the project’s pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
Jackson Code Example
MapToPojoWithJackson.java
public class MapToPojoWithJackson {
private static final Map<String, Object> employeemap = Map.of(
"department", new Department("Engineering", "Building A"),
"name", "Omos",
"projects", List.of(
new Project("Project A", "Developing new feature"),
new Project("Paris", "Bug fixing and maintenance")
)
);
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
Employee employee = objectMapper.convertValue(employeemap, Employee.class);
System.out.println(employee);
}
}
The code above initializes a Map named employeemap using the Map.of method. The map contains:
- A key
"department"with a value of aDepartmentobject. - A key
"name"with a value of aString. - A key
"projects"with a value of aListofProjectobjects.
ObjectMapper Initialization and Conversion:
ObjectMapper objectMapper = new ObjectMapper();– Creates an instance ofObjectMapper.Employee employee = objectMapper.convertValue(employeemap, Employee.class);– Converts theemployeemapto anEmployeeobject using theconvertValuemethod ofObjectMapper.
In summary, the code initializes a map with values representing an employee’s details and uses Jackson’s ObjectMapper to convert this map into an Employee POJO.
Output:
Employee{name=Omos, department=Department{name=Engineering, location=Building A}, projects=[Project{name=Project A, description=Developing new feature}, Project{name=Paris, description=Bug fixing and maintenance}]}
Ignore Unknown Properties
To configure Jackson to ignore unknown properties during deserialization, we can use the @JsonIgnoreProperties annotation on our POJO classes or configure the ObjectMapper directly. This is useful when a Map may contain additional fields that are not present in the Java classes.
The @JsonIgnoreProperties annotation can be used on a class level to specify that unknown properties should be ignored during deserialization by adding the @JsonIgnoreProperties(ignoreUnknown = true) annotation to our domain classes.
@JsonIgnoreProperties(ignoreUnknown = true)
class Department {
private String name;
private String location;
}
We can also configure the ObjectMapper to globally ignore unknown properties.
ObjectMapper objectMapper = new ObjectMapper();
// Configure the mapper to ignore unknown properties
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Employee employee = objectMapper.convertValue(employeemap, Employee.class);
Setting DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES to false configures Jackson to ignore unknown properties globally.
4. Cast Map to POJO with Gson
Gson is a Java library that can be used to convert Java Objects into their JSON representation and vice versa.
Add Gson Dependency
Add the following dependency to the project’s pom.xml:
pom.xml
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
Gson Code Example
Now, we can use Gson to map a Map to a domain object.
GsonMappingExample.java
public class GsonMappingExample {
public static void main(String[] args) {
Map<String, Object> employeeMap = new HashMap<>();
employeeMap.put("name", "Alice Booker");
Map<String, Object> departmentMap = new HashMap<>();
departmentMap.put("name", "Sales");
departmentMap.put("location", "Building C");
Map<String, Object> project1Map = new HashMap<>();
project1Map.put("name", "Project Epsilon");
project1Map.put("description", "Write functional requirements");
Map<String, Object> project2Map = new HashMap<>();
project2Map.put("name", "Project Zeta");
project2Map.put("description", "Write non-functional requirements");
employeeMap.put("department", departmentMap);
employeeMap.put("projects", List.of(project1Map, project2Map));
Gson gson = new Gson();
String jsonMap = gson.toJson(employeeMap);
Employee employee = gson.fromJson(jsonMap, Employee.class);
System.out.println(employee);
}
}
In this example:
- A
Gsonobject is created to handle the JSON serialization and deserialization. gson.toJson(employeeMap)serializes theemployeeMapinto a JSON string.gson.fromJson(jsonMap, Employee.class)deserializes the JSON string back into anEmployeeobject.
Output:
5. Conclusion
Direct casting from a Map to a POJO without using a library like Jackson or Gson does not work because of fundamental differences in data structure. To correctly perform such a conversion, we need to use a library that can handle the deserialization process, mapping the key-value pairs in a Map to the corresponding fields in the POJO.
This article explored various techniques for casting nested maps to POJOs in Java. We began by defining our domain classes—Employee, Department, and Project and then demonstrated how to use the Gson and Jackson library to convert a map into a POJO.
6. Download the Source Code
This was an example of how to cast a Map to a POJO (Plain Old Java Object) in Java.
You can download the full source code of this example here: Java Cast Map to POJO


