代码之家  ›  专栏  ›  技术社区  ›  Mulgard

Lombok+Jackson=>不匹配的输入异常

  •  0
  • Mulgard  · 技术社区  · 6 年前

    我有一个 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 从A 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 (尽管至少存在一个创建者):没有字符串参数构造函数/工厂方法可从字符串值(“”\“Street\”:\“Some Street\”,\“House\U Number\”:\“Some House Number\”')反序列化

    我找不到这个问题的根源,因为字段是匹配的,不是吗? 我也尝试过没有 @Builder 并使用 @Data , @AllArgsConstructor @NoArgsConstructor 相反。

    使用时得到相同的结果 readValue 而不是 convertValue

    1 回复  |  直到 6 年前
        1
  •  1
  •   pirho    6 年前

    如评论中所述,使用

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

    应该工作得很好,至少对我来说是这样。然而,在这一变化之后,您可能会遇到:

    com.fasterxml.jackson.databind.exc.unrecognizedpropertyException:无法识别字段“房屋编号”…

    (而不是原来的错误),将通过对您的 UserAddressBuilder :

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

    Javadoc :

    public t convertValue(对象FromValue,类ToValueType)
    引发IllegalArgumentException

    从给定值到给定值类型实例进行两步转换的方便方法。 这相当于首先将给定值序列化为JSON,然后将JSON数据绑定为给定类型的值。 但可以在不完全序列化为JSON的情况下执行。相同的转换器(序列化程序、反序列化程序)将用于数据绑定,这意味着相同的对象映射器配置可以工作。

    虽然 readValue 用于从字符串、流、读卡器读取到对象值。用 convertValue(..) 您可能需要定义转换器,但在您的情况下不需要它。