@JsonMerge проверяет существование с помощью List - PullRequest
0 голосов
/ 08 июня 2018

Мы реализуем аннотацию @JsonMerge в Jackson 2.9.

Согласно документации «Объединение коллекций простое: записи добавляются; проверки существования не применяются».

Однако,поскольку мы объединяем объекты JPA, мы не можем использовать Set (из-за проблем с отложенной загрузкой), мы должны использовать List.

Вопрос в том, как мы можем проверить существование при использовании Collection?

1 Ответ

0 голосов
/ 08 июня 2018

В итоге мы решили эту проблему, внедрив специальный десериализатор коллекции, который просто удаляет «дубликат» объекта из коллекции.

Не думаю, что это идеально, но отлично работает для наших нужд.

Публикация кода здесь на случай, если он пригодится кому-то другому.

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

Вызывается его из BeanDeserializerModifier, например, так:

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