2017-07-26 3 views
1

Ich versuche, ein Objekt, das eine OneToOne-Beziehung zu einem anderen polymorphen Objekt hat, zu PATCHIEREN. Die Aufgabe, die die Beziehung zu besitzen sieht wie folgt aus (I irrelevant JPA Annotationen und Felder weggelassen haben):JsonMappingException beim PATCH zu einem Spring Data REST-Repository

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

Das referenzierte Objekt sieht wie folgt aus:

@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(); 
     } 
} 

das Kind Objekte haben nichts Besonderes, nur einige verschiedene Felder (auch hier sind die Felder oben weggelassen), sie haben kein Repository, sondern werden alle über das PolicyRepository abgewickelt.

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:?] 

Dieser Fehler tritt auf, wenn das Patchen über CocoaRest UND: Jetzt, wenn ich versuche, eine Politik mit einem Körper zu patchen, die den exakt gleichen Inhalt von einem GET auf/Politik/2, bekomme ich diese Ausnahme abgerufen haben beim PATCHing via Retrofit. Das Interessante ist, dass die Client-Seite (Retrofit) in der Lage ist, das JSON korrekt zu deserialisieren (Jackson-Versionen sind auf der Client- und Serverseite gleich). Der Inhalt gesendet sieht wie folgt aus:

{ 
    "id": 2, 
    /* some fields */ 
    "channelFlow": { 
     "id": 1, 
     /* some fields */ 
     "type": "com.somepackage.VehicleChannelFlowConfig" 
    } 
} 

Jede Idee, was ich falsch mache? Danke!

Edit: Auch wenn ich einen ObjectMapper auf meinem Server manuell registriert, ist es in der Lage, den JSON zu deserialisieren. Ich bin Ideen aus jetzt :-(

Edit # 2:. Das Problem ist Spring DomainObjectReader, der Code

if (!mappedProperties.hasPersistentPropertyForField(fieldName)) { 
    i.remove(); 
} 

die korrekt übertragen Typanmerkung entfernt Dies scheint ein Problem mit Frühling zu sein, sich ., Jackson arbeitet gut

Antwort

0

Dies ist ein Problem mit dem Spring-Data-Version ist, die wir verwenden (4.5.5) wurde die DomainObjectReader werfen einfach weg jede JSON-Eigenschaften, die keine persistenten Felder waren (was ein Typfeld offensichtlich nicht ist). Es wurde wahrscheinlich durch dieses Commit behoben: https://github.com/spring-projects/spring-data-rest/commit/4150688851323e54967cacfbcd0d6a7e00c41980, das darauf abzielte, transiente Felder einzuschließen (nicht wirklich das Problem, dem ich begegnete, aber ein ähnliches).

0

Try this:

@JsonProperty(access = READ_ONLY) 
public String getType() { 
    return getClass().getName(); 
} 

Meiner Meinung nach orphanRemoval = true überflüssig ist, da Sie nur PERSIST und MERGE Kaskadentypen gesetzt ...

+0

READ_ONLY leider ändert nichts :-( – N4zroth