GraphQL не десериализует java-тип LocalDate

150
22 ноября 2019, 22:20

У меня в проекте используется GraphQL, и я пытаюсь замапить даты на поле типа LocalDate. Запрос такой:

mutation {
  updateInvoice(invoice: {
    uid: "1d8444cc-6033-4fc5-bcf5-9b488b389702",
    date: "2019-02-06",
    arrivalDate: "2019-02-06",
    number: "18-000123123",
    departureKLADR: "7800000000000000000000000",
    arrivalKLADR: "7700000000000000000000000",
    freightInKops: 1000000,
    cargoKind: "Мебель",
    amount: 1,
    netVolume: 3.3,
    netWeight: 275.3,
    declaredValueInKops: 1000,
  })
}

Класс энтити выглядит приблизительно так:

@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"}, ignoreUnknown = true)
public class Invoice extends BlockchainEntity {
    private static final Log log = LogFactory.getLog(Invoice.class);
    @Id
    @Column(name = "UID")
    @JsonProperty("uid")
    private UUID uid;
    //@JsonSerialize(using = com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer.class)
    //@JsonDeserialize(using = com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer.class)
    @JsonSerialize(converter = LocalDateSerializer.class)
    @JsonDeserialize(converter = LocalDateDeserializer.class)
    private LocalDate date;
    @Column(name = "ARRIVAL_DATE")
    @JsonProperty(value = "dateOfArrival")
    @JsonSerialize(converter = LocalDateSerializer.class)
    @JsonDeserialize(converter = LocalDateDeserializer.class)
    private LocalDate arrivalDate;
    public Invoice() {
    }
    public UUID getUid() {
        return uid;
    }
    public void setUid(UUID uid) {
        this.uid = uid;
        System.out.println("SetUID CALLED");
    }
    public LocalDate getDate() {
        return date;
    }
    @JsonProperty("date")
    public void setDate(LocalDate date) {
        System.out.println("SetDate CALLED");
        this.date = date;
    }
    public LocalDate getArrivalDate() {
        return arrivalDate;
    }
    public void setArrivalDate(LocalDate arrivalDate) {
        this.arrivalDate = arrivalDate;
    }
}

Я удалил поля, которые не нужны.

В схеме input-тип объявлен так:

input UpdateInvoiceInput {
    uid: UUID
    number: String
    date: LocalDate!
    arrivalDate: LocalDate
    departureKLADR: String
    arrivalKLADR: String
    departureCityName: String
    arrivalCityName: String
    freightInKops: Long
    cargoKind: String
    amount: Int
    netVolume: Float
    netWeight: Float
    declaredValueInKops: Long
    policyRows: [InsurancePolicyRowInput]
}

Есть определение скаляра scalar LocalDate.

Класс скаляра такой:

import java.time.LocalDate;
@Component
public class LocalDateScalarType extends GraphQLScalarType {
    public LocalDateScalarType() {
        super("LocalDate", "LocalDate value", new Coercing<LocalDate, String>() {
            @Override
            public String serialize(Object o) throws CoercingSerializeException {
                if (o == null) {
                    return null;
                } else if (o instanceof LocalDate) {
                    return DateTimeUtils.serializeDate((LocalDate) o);
                } else {
                    throw new CoercingSerializeException("Not LocalDate object.");
                }
            }
            @Override
            public LocalDate parseValue(Object o) throws CoercingParseValueException {
                if (o == null) {
                    return null;
                } else if (o instanceof LocalDate) {
                    return (LocalDate) o;
                } else if (o instanceof String) {
                    return DateTimeUtils.parseDate((String) o);
                } else if (o instanceof StringValue) {
                    return DateTimeUtils.parseDate(((StringValue) o).getValue());
                } else {
                    throw new CoercingParseValueException("Unparsable value");
                }
            }
            @Override
            public LocalDate parseLiteral(Object o) throws CoercingParseLiteralException {
                System.out.println("parseLiteral CALLED");
                if (o == null) {
                    return null;
                } else if (o instanceof LocalDate) {
                    System.out.println(((LocalDate)o).toString());
                    return (LocalDate) o;
                } else if (o instanceof String) {
                    return DateTimeUtils.parseDate((String) o);
                } else if (o instanceof StringValue) {
                    LocalDate localDate = DateTimeUtils.parseDate(((StringValue) o).getValue());
                    return localDate;
                } else {
                    throw new CoercingParseLiteralException("Unparsable value");
                }
            }
        });
    }
}

Проблема в том, что дата успешно десериализуется внутри метода parseLiteral, но в класс Invoice значение даты не попадает, и я получаю ошибку:

Exception while fetching data (/updateInvoice) : Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

Я сделал логгирование в некоторых методах и оказалось, что порядок вызова методов такой: несколько раз вызывается parseLiteral, потом вызывается сеттер для UID, а сеттер для date не вызывается вообще.

Почему дата может не устанавливаться? Я использовать как велосепидный десериализатор LocalDate, так и десериализатор из библиотеки jackson-datatype-jsr310, но это не помогло.

READ ALSO
Как искать данные в нижним регистре Firebase database?

Как искать данные в нижним регистре Firebase database?

Поисковить у меня работает так

103
Будильник не срабатывает

Будильник не срабатывает

Пишу код будильника для своего приложения, но он не срабатывает

141
Написание Unit - тестов в Android

Написание Unit - тестов в Android

Всем привет, пишу тестовое задание на Android - разработчика, и одним из требований является написание нескольких Jnit тестов (которые я ни разу...

124
Webkit android вывод элементов

Webkit android вывод элементов

Если ли какая нибудь возможность в webkit выводить определенные элементы/блоки со страницы сайта, работоспособныеНапример, есть мобильная...

119