首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JsonMappingException而PATCHing到Spring数据REST库

JsonMappingException而PATCHing到Spring数据REST库
EN

Stack Overflow用户
提问于 2017-07-26 12:02:22
回答 2查看 357关注 0票数 1

我试图修补一个对象,该对象与另一个多态对象有OneToOne关系。拥有这种关系的对象如下所示(我省略了无关的JPA注释和字段):

代码语言:javascript
复制
public class Policy extends BaseEntity {
    @Valid
    @NotNull
    @OneToOne(optional = false, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)
    @JoinColumn(name = "CHANNELFLOW_ID")
    private ChannelFlowConfig channelFlow;
}

引用的对象如下所示:

代码语言:javascript
复制
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name = "CHANNELFLOWCONFIG")
public abstract class ChannelFlowConfig extends BaseEntity {
        @JsonProperty("type")
        public String getType() {
            return getClass().getName();
        }
}

子对象没有什么特殊的,只是一些不同的字段(同样,上面省略了字段),它们没有存储库,而是都通过PolicyRepository处理。现在,当我试图用从GET / Policy /2中检索到的内容完全相同的主体修补策略时,我得到了以下异常:

代码语言:javascript
复制
Caused by: com.fasterxml.jackson.databind.JsonMappingException: 
Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'type' that is to contain type id  (for class com.vw.mbbc.authserver.model.policy.ChannelFlowConfig)
at [Source: N/A; line: -1, column: -1] (through reference chain: com.vw.mbbc.authserver.model.policy.Policy["channelFlow"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1376) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.DeserializationContext.reportWrongTokenException(DeserializationContext.java:1197) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:165) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:105) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:209) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:502) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:240) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1628) ~[jackson-databind-2.8.9.jar:2.8.9]
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1301) ~[jackson-databind-2.8.9.jar:2.8.9]
at org.springframework.data.rest.webmvc.json.DomainObjectReader.doMerge(DomainObjectReader.java:222) ~[spring-data-rest-webmvc-2.5.5.RELEASE.jar:?]
at org.springframework.data.rest.webmvc.json.DomainObjectReader.read(DomainObjectReader.java:77) ~[spring-data-rest-webmvc-2.5.5.RELEASE.jar:?]

当PATCHing通过CocoaRest和PATCHing通过Retrofit时会发生此错误。有趣的是,客户端(Retrofit)能够正确地反序列化JSON (Jackson版本在客户端和服务器端是相同的)。发送的内容如下:

代码语言:javascript
复制
{
    "id": 2,
    /* some fields */
    "channelFlow": {
        "id": 1,
        /* some fields */
        "type": "com.somepackage.VehicleChannelFlowConfig"
    }
}

知道我做错什么了吗?谢谢!

编辑:即使我手动在服务器上注册了一个ObjectMapper,它也能够反序列化JSON。我现在没有主意了:-

编辑#2:问题是Spring的DomainObjectReader,代码

代码语言:javascript
复制
if (!mappedProperties.hasPersistentPropertyForField(fieldName)) {
    i.remove();
}

移除正确传输的类型注释。这似乎是Spring本身的一个问题,杰克逊工作得很好。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-27 09:04:53

这是我们使用的Spring版本的一个问题(4.5.5),DomainObjectReader只是丢弃了任何不是持久字段的JSON属性(类型字段显然不是)。它可能是通过这个commit:https://github.com/spring-projects/spring-data-rest/commit/4150688851323e54967cacfbcd0d6a7e00c41980修复的,它的目标是包含瞬态字段(不是我遇到的问题,而是类似的问题)。

票数 0
EN

Stack Overflow用户

发布于 2017-07-26 12:28:50

试试这个:

代码语言:javascript
复制
@JsonProperty(access = READ_ONLY)
public String getType() {
    return getClass().getName();
}

在我看来,orphanRemoval = true是多余的,因为您只设置了PERSISTMERGE级联类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45326416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档