Ломбок + Джексон => MismatchedInputException - PullRequest
0 голосов
/ 31 января 2019

У меня есть таблица PSQL с одним столбцом, содержащим данные jsonb:

CREATE TABLE IF NOT EXISTS user (
    user_name VARCHAR(255) NOT NULL,
    user_email VARCHAR(255) NOT NULL,
    user_address jsonb NOT NULL
)

Для этого у меня есть java object:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Value;

@Value
@Builder
public class User {
    private String userName;
    private String userEmail;
    private UserAddress address;

    @Value
    @Builder
    @JsonDeserialize(builder = UserAddress.UserAddressBuilder.class)
    public static class UserAddress {
        @JsonProperty("street")
        private String street;
        @JsonProperty("house_number")
        private String houseNumber;

        @JsonPOJOBuilder(withPrefix = "")
        public static class UserAddressBuilder {
            private String street = null;
            private String houseNumber = null;

            public UserAddressBuilder street(String street) {
               this.street = street;

               return this;
            }

            public UserAddressBuilder houseNumber(String houseNumber) {
                this.houseNumber = houseNumber;

                return this;
            }
        }
    }
}

Когда я сейчаспостроить User из ResultSet:

return User.builder()
        .userName(rs.getString(SqlConstants.TableUser.USER_NAME))
        .userEmail(rs.getString(SqlConstants.TableUser.USER_EMAIL))
        .userAddress(mapper.convertValue(rs.getString(SqlConstants.TableUser.USER_ADDRESS), User.UserAddress.class))
        .build();

Я всегда получаю исключение:

Причина: com.fasterxml.jackson.databind.exc.MismatchedInputException:Невозможно создать экземпляр my.package.model.User$UserAddress$UserAddressBuilder (хотя существует хотя бы один создатель): нет конструктора аргумента String / метода фабрики для десериализации из значения String ('"{\" street \ ": \" Some Street \ ", \" house_number \)": \" Некоторый номер дома \ "} ')

Я не могу найти источник этой проблемы, поскольку поля совпадают, не так ли? Я также попробовал подход без @Builder и использовал @Data, @AllArgsConstructor и @NoArgsConstructor вместо.

Я получаю тот же результат при использовании readValue вместо convertValue

1 Ответ

0 голосов
/ 31 января 2019

Как уже упоминалось в комментариях, использование

.userAddress(mapper.readValue(rs.getString(SqlConstants.TableUser.USER_ADDRESS), 
                                              User.UserAddress.class))

должно работать просто отлично, по крайней мере, для меня.Однако после этого изменения вы можете столкнуться с:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: нераспознанное поле "house_number" ...

(вместоисходная ошибка), которая будет исправлена ​​небольшим изменением вашей UserAddressBuilder:

@JsonProperty("house_number") // this is also needed to map correctly
public UserAddressBuilder houseNumber(String houseNumber) { ...

From Javadoc :

public T convertValue (Object fromValue, Class toValueType)
генерирует IllegalArgumentException

Удобный метод для выполнения двухшагового преобразования из заданного значения в экземпляр заданного типа значения. Эта функциональность эквивалентна первой сериализации заданного значения в JSON, затем привязке данных JSON к значению данного типа , но может выполняться без полной сериализации в JSON.Те же конвертеры (сериализаторы, десериализаторы) будут использоваться, как и для связывания данных. Это означает, что конфигурация сопоставителя объектов работает одинаково

, а readValue - для чтения из строки, потока, считывателя в значение объекта.С convertValue(..) вам могут понадобиться определенные конвертеры, но в вашем случае это не нужно.

...