How to map generic collections with Spring Data(MongoDB)?
I have some problems with mapping my inner collection. Items can have different content types. Here is my Item class:
@Document(collection = "items")
public class Item{
@Id
priv开发者_如何学Cate ObjectId id;
private List<? super Content> content;
...
}
Content is a base class for different content for this Item.
public class YoutubeVideo implements Content{
private String url;
}
public class Image implements Content{
private String location;
}
...
After saving (saving finishing with no problems) Item with one Image and two YoutubeVideo classes in content collection i getting this JSON
{ "_id" : { "$oid" : "4e423dcf7f3a0d12265da46c"}
"content" : [
{ "location" : "hdd path"} , { "url" : "url path"} , { "url" : "url path"}
]}
It is not this JSON I expected to see. And understandable why it is not possible to load and deserialize this document.
java.lang.RuntimeException: Can not map ? super trngl.mongo.domain.content.Content
How you would map this kind of object? I do not want to serialize and deserialize objects manualy. Is it possible?
Found interestion converters class: mapping-explicit-converters
It should be sufficient to use List<Content>
as you can't access the concrete types from a mixed content list anyway. (Btw. super is definitely wrong here as your not storing supertyes of Content
but subtypes. Extends on the other hand wouldn't add any additional value).
List<Content>
should work with the latest snapshots for MongoTemplate
as we fixed quite some bugs since the last milestone release. If you're using our repository abstraction make sure Content
is an abstract class containing the id property. There is an open issue you might wanna watch for us to support interfaces as repository managed types as well.
Just as an FYI (since we hunted for this for a good morning after trying to figure out why we were getting our objects returned as LinkedHashMaps
of the members), this issue also occurs (in 1.0.2.RELEASE), when you try to store a Collection<Content>
in the form:
@Document(collection = "items")
public class Item{
@Id
private ObjectId id;
private Collection<Content> content;
...
}
The solution, as above, is to switch it to a List<Content>
.
Code List<? super Content> content;
creates list with elements, with type, which extends class Content. As I see, Content - is an interface, so you cannot specify generic binding for it.
I'd suggest you to create abstract class Content and extend this class by your classes YoutubeVideo and Image. After that, code List<? super Content> content;
will work fine.
Sergey.
精彩评论