Reputation: 13481
I´m trying to deserialize a json into scala class, that contains a Collection of types Aclass,Bclass or Cclass
class Results[M](results:util.ArrayList[M]) {
def getResults:util.ArrayList[M]=results
def this() {
this(new util.ArrayList())
}
}
The Json looks like:
{ "results":[{"a":1},{"a":1}]}
or
{ "results":[{"b":1},{"b":1}]}
or
{ "results":[{"b":1},{"b":1}]}
Here my object mapper
val mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
And here how I deserialize a json of class type Aclass
val results = mapper.readValue(json, classOf[Results[Aclass]])
The problem is that results, return a ArrayList where every element instead to be an instance of Aclass, is a LinkedHashMap
.
If I change the code instead to use generic I make it explicit in the type
class Results[Aclass](results:util.ArrayList[Aclass]) {
def getResults:util.ArrayList[Aclass]=results
def this() {
this(new util.ArrayList())
}
}
It works and return an class with result of array of Aclass elements.
What I´m doing wrong here?. I think it´s a bug in the library
Regards.
Upvotes: 0
Views: 640
Reputation: 106
The reason is that java.lang.Class
does not hold information about generic parameters. The value of classOf[Result[Aclass]]
is java.lang.Class. It does not have information about the type parameter Aclass
. It represents only the Results
class.
The mapper does what you ask for: gives you Results
of whatever and the best whatever for it is a map.
To solve it, use readValue method that takes JavaType
instead. JavaType
can be created using TypeFactory
:
val results:Results[Aclass] = mapper.readValue(json, mapper.getTypeFactory()
.constructParametricType(classOf[Results[_]], classOf[Aclass]))
Upvotes: 3