简体   繁体   中英

@JsonMerge check existence with List

We are implementing Jackson 2.9's @JsonMerge annotation.

As per the documentation "Merging of Collections is simple: entries are appended; no checks for existence applied".

However, because we are merging JPA entities, we cannot use Set (due to issues with lazy loading), we must use List.

The question is, how can we check for existence when using a Collection?

We ended up solving this by implementing a custom collection deserializer that simply removes the "duplicate" object from the collection.

I don't think it's ideal but works perfectly for our needs.

Posting the code here in case it's of use to someone else.

public class UniqueCollectionDeserializer extends CollectionDeserializer {
    public UniqueCollectionDeserializer(
        JavaType collectionType,
        JsonDeserializer<Object> valueDeser,
        TypeDeserializer valueTypeDeser,
        ValueInstantiator valueInstantiator
    ) {
        super(collectionType, valueDeser, valueTypeDeser, valueInstantiator);
    }

    protected UniqueCollectionDeserializer(
        JavaType collectionType,
        JsonDeserializer<Object> valueDeser,
        TypeDeserializer valueTypeDeser,
        ValueInstantiator valueInstantiator,
        JsonDeserializer<Object> delegateDeser,
        NullValueProvider nuller,
        Boolean unwrapSingle
    ) {
        super(collectionType, valueDeser, valueTypeDeser, valueInstantiator, delegateDeser, nuller, unwrapSingle);
    }

    public UniqueCollectionDeserializer(CollectionDeserializer defaultDeserializer) {
        super(defaultDeserializer);
    }

    @Override
    public Collection<Object> deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
        return removeDuplicates(super.deserialize(jsonParser, context));
    }

    @Override
    public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt, Collection<Object> result) throws IOException {
        return removeDuplicates(super.deserialize(p, ctxt, result));
    }

    @SuppressWarnings("unchecked")
    @Override
    protected CollectionDeserializer withResolved(
        JsonDeserializer<?> dd,
        JsonDeserializer<?> vd,
        TypeDeserializer vtd,
        NullValueProvider nuller,
        Boolean unwrapSingle
    ) {
        return new UniqueCollectionDeserializer(_containerType, (JsonDeserializer<Object>) vd, vtd, _valueInstantiator, (JsonDeserializer<Object>) dd, nuller, unwrapSingle);
    }

    private Collection<Object> removeDuplicates(Collection<Object> data) {
        return data.stream()
                .distinct()
                .collect(Collectors.toList());
    }
}

Called it from a BeanDeserializerModifier like so:

public JsonDeserializer<?> modifyCollectionDeserializer(DeserializationConfig config, CollectionType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
    return new UniqueCollectionDeserializer((CollectionDeserializer) deserializer);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM