'java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.testing.models.Account
I'm getting below error:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.testing.models.Account
with below code
final int expectedId = 1;
Test newTest = create();
int expectedResponseCode = Response.SC_OK;
ArrayList<Account> account = given().when().expect().statusCode(expectedResponseCode)
.get("accounts/" + newTest.id() + "/users")
.as(ArrayList.class);
assertThat(account.get(0).getId()).isEqualTo(expectedId);
Is there a reason why I cannot do get(0)?
Solution 1:[1]
Try the following:
POJO pojo = mapper.convertValue(singleObject, POJO.class);
or:
List<POJO> pojos = mapper.convertValue(
listOfObjects,
new TypeReference<List<POJO>>() { });
See conversion of LinkedHashMap for more information.
Solution 2:[2]
The way I could mitigate the JSON Array to collection of LinkedHashMap objects problem was by using CollectionType rather than a TypeReference .
This is what I did and worked:
public <T> List<T> jsonArrayToObjectList(String json, Class<T> tClass) throws IOException {
ObjectMapper mapper = new ObjectMapper();
CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, tClass);
List<T> ts = mapper.readValue(json, listType);
LOGGER.debug("class name: {}", ts.get(0).getClass().getName());
return ts;
}
Using the TypeReference, I was still getting an ArrayList of LinkedHashMaps, i.e. does not work:
public <T> List<T> jsonArrayToObjectList(String json, Class<T> tClass) throws IOException {
ObjectMapper mapper = new ObjectMapper();
List<T> ts = mapper.readValue(json, new TypeReference<List<T>>(){});
LOGGER.debug("class name: {}", ts.get(0).getClass().getName());
return ts;
}
Solution 3:[3]
I had a similar exception (but different problem) - java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.bson.Document , and fortunately it's solved easier:
Instead of
List<Document> docs = obj.get("documents");
Document doc = docs.get(0)
which gives error on second line, One can use
List<Document> docs = obj.get("documents");
Document doc = new Document(docs.get(0));
Solution 4:[4]
Solve problem with two method parse common
- Whith type is an object
public <T> T jsonToObject(String json, Class<T> type) {
T target = null;
try {
target = objectMapper.readValue(json, type);
} catch (Jsenter code hereonProcessingException e) {
e.printStackTrace();
}
return target;
}
- With type is collection wrap object
public <T> T jsonToObject(String json, TypeReference<T> type) {
T target = null;
try {
target = objectMapper.readValue(json, type);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return target;
}
Solution 5:[5]
This is something i used in my project, Json object was returned, i converted it to a List of POJO, List and then accessed the element. I took the input of Json object from another microservice.
Main thing is:- JsonNode stocks = restTemplate.getForObject("http://localhost:2000/stocks/qty", JsonNode.class); List<Stock_id_qty> stockList = mapper.convertValue(stocks, new TypeReference<List<Stock_id_qty>>() {});
@GetMapping("/")
public List<Stock_id_qty> checkQty() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
JsonNode stocks = restTemplate.getForObject("http://localhost:2000/stocks/qty", JsonNode.class);
List<Stock_id_qty> stockList = mapper.convertValue(stocks, new TypeReference<List<Stock_id_qty>>() {});
List<Stock_id_qty> result = new ArrayList<>();
for(Stock_id_qty s : stockList){
if(s.getStockQty() < 10)
{
result.add(s);
}
}
return result;
}
Solution 6:[6]
I have this method for deserializing an XML and converting the type:
public <T> Object deserialize(String xml, Class objClass ,TypeReference<T> typeReference ) throws IOException {
XmlMapper xmlMapper = new XmlMapper();
Object obj = xmlMapper.readValue(xml,objClass);
return xmlMapper.convertValue(obj,typeReference );
}
and this is the call:
List<POJO> pojos = (List<POJO>) MyUtilClass.deserialize(xml, ArrayList.class,new TypeReference< List< POJO >>(){ });
Solution 7:[7]
When you use jackson to map from string to your concrete class, especially if you work with generic type. then this issue may happen because of different class loader. i met it one time with below scenarior:
Project B depend on Library A
in Library A:
public class DocSearchResponse<T> {
private T data;
}
it has service to query data from external source, and use jackson to convert to concrete class
public class ServiceA<T>{
@Autowired
private ObjectMapper mapper;
@Autowired
private ClientDocSearch searchClient;
public DocSearchResponse<T> query(Criteria criteria){
String resultInString = searchClient.search(criteria);
return convertJson(resultInString)
}
}
public DocSearchResponse<T> convertJson(String result){
return mapper.readValue(result, new TypeReference<DocSearchResponse<T>>() {});
}
}
in Project B:
public class Account{
private String name;
//come with other attributes
}
and i use ServiceA from library to make query and as well convert data
public class ServiceAImpl extends ServiceA<Account> {
}
and make use of that
public class MakingAccountService {
@Autowired
private ServiceA service;
public void execute(Criteria criteria){
DocSearchResponse<Account> result = service.query(criteria);
Account acc = result.getData(); // java.util.LinkedHashMap cannot be cast to com.testing.models.Account
}
}
it happen because from classloader of LibraryA, jackson can not load Account class, then just override method convertJson in Project B to let jackson do its job
public class ServiceAImpl extends ServiceA<Account> {
@Override
public DocSearchResponse<T> convertJson(String result){
return mapper.readValue(result, new TypeReference<DocSearchResponse<T>>() {});
}
}
}
Solution 8:[8]
public class ObjectHelper { private static ObjectMapper objectMapper = new ObjectMapper(); public static ObjectMapper getObjectMapper() { objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); return objectMapper; } }
Use
FetchResponse fetchResponse = ObjectHelper.getObjectMapper().convertValue( data, new TypeReference<FetchResponse>() {});
OR
List<Map<String, Object>> responseObj = (List<Map<String, Object>>) response.get("content");
List<LkAuthUserDetail> responseData = ObjectHelper.getObjectMapper().convertValue(responseObj,
new TypeReference<List<LkAuthUserDetail>>() {});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ErikE |
| Solution 2 | Himadri Pant |
| Solution 3 | |
| Solution 4 | Love Java |
| Solution 5 | siddharth jain |
| Solution 6 | Ishaan Javali |
| Solution 7 | uncle bob |
| Solution 8 |
