spring-projects / spring-data-rest

Simplifies building hypermedia-driven REST web services on top of Spring Data repositories
https://spring.io/projects/spring-data-rest
Apache License 2.0
919 stars 563 forks source link

Mapping with @JsonTypeInfo not working [DATAREST-304] #683

Open spring-projects-issues opened 10 years ago

spring-projects-issues commented 10 years ago

Johannes Hiemer opened DATAREST-304 and commented

When using @JsonTypeInfo in classes, the mapping is done incorrectly in Spring Data REST.

Here are my mapping files:

https://gist.github.com/jhiemer/f95ca403dc849692f482

{
  "@class": "de.model.ChildTwo",
  "up": 90,
  "timespan" : 438948948,
}

This saves a trigger, but does not store the information of ChildTwo. I am pretty sure this has worked in previous versions


Affects: 2.1 RC1 (Dijkstra)

Issue Links:

11 votes, 12 watchers

spring-projects-issues commented 10 years ago

Johannes Hiemer commented

I did some further debugging. Making the Parent class abstract lets me save the entities with the specific type information, but I still think that SD REST does not handle JsonTypeInfo properly. The reason is as follows. Having changed Parent.java to abstract leads to the following scenario: all entities are stored in the "parent" collection of MongoDB, but when doing a GET no class information is provided. Is this intended behaviour? If yes, this should be changed, because it leads you to a best guess approach on the client side, based on the mapping properties of the returned entity

spring-projects-issues commented 9 years ago

Thomas Eizinger commented

Any updates on this? I am currently facing the same issue, athough I was able to persist the entity, if the type information is provided as configured. (@JsonSubType) However, the type information is not provided on serialization. For example, if I issue the following post:

{
    "$type": "FreeTextAnswer",
    "answerText": "50",
    "question": "http://localhost:8080/questions/351",
    "test": "http://localhost:8080/tests/290"
}

The typemapping is correctly handled by jackson but the entity is returned without type information:

{
    "createdAt": "2014-12-16T21:19:29.857+01:00",
    "modifiedAt": "2014-12-16T21:19:29.857+01:00",
    "answerText": "50",
    "_links": {
        "self": {
            "href": "http://localhost:8080/answers/370"
        },
        "test": {
            "href": "http://localhost:8080/answers/370/test"
        },
        "question": {
            "href": "http://localhost:8080/answers/370/question"
        }
    }
}
spring-projects-issues commented 9 years ago

Johannes Hiemer commented

I am also able to persist the data with the current builds, but I would still expect on the abstract entity the @class annotation to be exposed as well

spring-projects-issues commented 9 years ago

Thomas Eizinger commented

Do you remember a build version that did expose this data?

spring-projects-issues commented 9 years ago

Johannes Hiemer commented

Not really, could have been February or so. No idea. Sorry. :-(

spring-projects-issues commented 9 years ago

Pablo Santiago commented

I think I found the problem why type is not rendered.

Instead of serializing a ChildTwo object, what gets serialized by Jackson is a Resource<ChildTwo>. Resource has a generic public T getContent() with a @JsonUnwrapped annotation in order to render the desired entity.

However, because of type erasure, T resolves to Object and thus BeanSerializerFactory#findPropertyTypeSerializer returns null since, clearly, there isn't one for type Object.

Furthermore, Resource<Object> is explicitly declared in PersistentEntityJackson2Module.PersistentEntityResourceSerializer and PersistentEntityResource which extends Resource<Object>.

Lastly, if Resource#getContent does not contain @JsonTypeInfo Jackson won't even try to resolve the @JsonTypeName of the target entity.

The only workaround that I found so far was to simple add the type information as a @JsonGetter in the parent class like this:

@JsonGetter(value = "$type")
public String getType() {
    return this.getClass().getSimpleName();
}
spring-projects-issues commented 9 years ago

Sébastien Deleuze commented

I think we solved a related issue in Spring Framework 4.2 with SPR-12811 and SPR-13318 (enabled only with Jackson 2.6+ for serializing collections), not sure if it can help here but I think this is worth to have a look

spring-projects-issues commented 7 years ago

Craig commented

I believe this is a duplicate of DATAREST-900

spring-projects-issues commented 7 years ago

Daniele Renda commented

Some news about this issue? Thanks