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

Cannot construct instance of java.io.Serializable even though @JsonDeserialize is present [DATAREST-1167] #1533

Open spring-projects-issues opened 6 years ago

spring-projects-issues commented 6 years ago

Petar Tahchiev opened DATAREST-1167 and commented

Project generated from start.spring.io (JPA, H2 and Rest) with the following JPA entity:

@Entity
public class ProductEntity {

    public static final String NAME = "product";

    @Id
    private Long id;

    @ElementCollection(targetClass = Serializable.class)
    @CollectionTable(name = (ProductEntity.NAME + "_dynamic_attribute"), joinColumns = { @JoinColumn(name = (ProductEntity.NAME + "_id")) }, indexes = {
                    @Index(name = (("idx_" + ProductEntity.NAME) + "_dynamic_attribute"), columnList = (ProductEntity.NAME
                                    + "_id")) }, foreignKey = @ForeignKey(name = (("fk_" + ProductEntity.NAME) + "_dynamic_attribute")))
    @MapKeyColumn(name = "code")
    @JsonDeserialize(contentUsing = StringDeserializer.class, contentAs = String.class)
    private Map<String, Serializable> dynamicAttribute;

    /* getters/setters */

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Map<String, Serializable> getDynamicAttribute() {
        return dynamicAttribute;
    }

    public void setDynamicAttribute(Map<String, Serializable> dynamicAttribute) {
        this.dynamicAttribute = dynamicAttribute;
    }
}

Then issue PATCH request to create new dynamic attribute, and I receive this exception:

Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.io.Serializable` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: UNKNOWN; line: -1, column: -1]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.execute(DomainObjectReader.java:671) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.lambda$doMerge$3(DomainObjectReader.java:261) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    at java.util.Optional.ifPresent(Optional.java:159) ~[na:1.8.0_151]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.doMerge(DomainObjectReader.java:239) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.read(DomainObjectReader.java:88) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    ... 58 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.io.Serializable` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: UNKNOWN; line: -1, column: -1]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451) ~[jackson-databind-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027) ~[jackson-databind-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265) ~[jackson-databind-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3972) ~[jackson-databind-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2264) ~[jackson-databind-2.9.2.jar:2.9.2]
    at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:2746) ~[jackson-databind-2.9.2.jar:2.9.2]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.doMergeNestedMap(DomainObjectReader.java:398) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.lambda$null$1(DomainObjectReader.java:262) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    at org.springframework.data.rest.webmvc.json.DomainObjectReader.execute(DomainObjectReader.java:669) ~[spring-data-rest-webmvc-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    ... 62 common frames omitted

My setup:

Will provide a sample project in a bit.


3 votes, 5 watchers

spring-projects-issues commented 6 years ago

Petar Tahchiev commented

Sample project is here: https://github.com/ptahchiev/DATAREST-1167

spring-projects-issues commented 6 years ago

Nayden gochev commented

using jackson-databind 2.9.2 with a plain object mapper provided by jackson it works as expected. But with Spring Data Rest it doesnt.

Keep in mind in the example above

@JsonDeserialize(contentUsing = StringDeserializer.class, contentAs = String.class)

we do not need both, we need one of them and any of them should work and none of them works ;)

spring-projects-issues commented 6 years ago

Petar Tahchiev commented

Any update on this one? :)

spring-projects-issues commented 6 years ago

Yoana Ivanova commented

I have the same problem. Any ideas for a fix or a work-around?

spring-projects-issues commented 6 years ago

Petar Tahchiev commented

Any news on this? Is there anything else I can do to further help with this?

spring-projects-issues commented 6 years ago

Teodor Tunev commented

Is there any progress on this issue?