1

There's a way to handle this validation ?

class java.lang.Integer cannot be cast to class java.lang.String

Code:

private List<Map<String,String>> getEmpRegistry(
        List<Map<String,String>> tblObjRowsList,
        Integer rowNumber
){
    List<Map<String,String>> empRegistry = new ArrayList<>();
    for (Map<String,String> empR : tblObjRowsList){
        if (empR.get("id").equals(rowNumber)){
            empRegistry.add(empR);
        }
    }
    return empRegistry;
}

Looks wrong, because I can't compare String and Integer.

But for some reason tblObjRowsList is extracted from stored procedure in MySQL via Spring Data:

@Query(value="CALL SP_ObjsRowDetails2(:Id,:templateId,:strMode)",nativeQuery = true)
List<Map<String,String>> getRowDetail  (@PathParam("Id") Integer id,
                                        @PathParam("templateId") Integer templateId,
                                        @PathParam("strMode") Integer strMode);

Extract the data like this:

enter image description here

I tried:

Integer.parseInt(empR.get("id")).equals(rowNumber)

Integer.parseInt(empR.get("id").toString()).equals(rowNumber)

empR.get("id").toString().equals(String.valueOf(rowNumber))

And the most interesting thing is:

enter image description here

Doesn't make sense, if the source variable is Map<String,String>

0

2 Answers 2

2

That declaration of List<Map<String,String>> getRowDetail(...) is probably a "lie". That's the problem with runtime, dynamic code generation...

Spring data generates the implementation for you, and there is no proof that it will generate a Map<String, String> in reality, it all depends on what the SQL type will actually be in your procedure

Spring can and will produce a Map but you can not know what types lie therein, the actual types will be chosen once the metadata for the SQL result set comes back.

The compiler is happy, because generics are erased after compilation anyway, so as long as it's a Map, it's fine.

In the end you only realise Spring did not do "the right thing" (or actually, what you expected, because in its view it did the right thing) until runtime.

There is no easy way out. Either you fully acknowledge the unknowable nature of the contents of the map, and declare a Map<Object, Object> as the return type. And your code will have to cast to operate on the data.

Or you make sure you adapt the Java to the SQL or vice-versa with less generic types (eg <String, Integer>) - and find a way to make sure nobody changes the SQL without applying the change to the Java side, or vice-versa.

Sign up to request clarification or add additional context in comments.

Comments

2

I believe that instead of Map<String, String> use Map<String, Object> and then according to the type inside of the value just cast it to to integer, string, or whatever.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.