使用构建器映射对象时定义无效

Invalid definition when using builder to map an object

我正在 Spring 通过休息模板拨打休息电话。

如果我用来映射的对象使用 Lombok 的 Getter/Setter,一切正常。

但是如果我使用 Builder,它会因 InvalidDefinitionException 错误而中断。

如果我按照错误并添加构造函数,它确实有效。

但我正在努力避免它。我只是想让字段最终化,让构建器处理构建。

我能否得到一些关于如何解决这个问题的建议,或者如果这是预期的并且不能简单地坚持只使用 Builder 并且确实需要构造函数?谢谢。

以下编译正常,但当我进行其余调用时,出现以下错误:

InvalidDefinitionException: Cannot construct instance of my.package.Genre (no Creators, like default constructor, exist): cannot deserialize from Object value

@Builder
@Getter
public class Genre {
    private long id;
    private String name;
}

失败的rest调用

return restTemplate.exchange(url, HttpMethod.GET, entity, Genre.class, params);

以下将在使用 Setter 时通过。使用上面相同的 rest 调用进行测试。

@Getter
@Setter
public class Genre {
    private long id;
    private String name;
}

或者,如果我添加了试图不做的构造函数,则以下内容也有效。

如果这是必须的,我会选择坚持 Setter。多多指教。

@Builder
@Getter
public class Genre {
    private long id;
    private String name;

    public Genre() {
    }

    public Genre(long id, String name) {
        this.id = id;
        this.name = name;
    }
}

这应该有效。

@Builder
@Getter
@NoArgsConstructor
public class Genre {
    private long id;
    private String name;
}

TDLR;如果没有定义其他构造函数,@Builder 隐式创建 all-args-constructor。 No-arg-constructor 通常由编译器自动添加的不会被添加。在这种情况下,RestTemplate 需要no-arg-constructor。所以我们添加一个。

从 Lombok 1.18.16 开始,您可以使用 @Jacksonized 自动生成 Jackson 使用 Lombok 所需的一切 @(Super)Builder:

@Jacksonized
@Builder
@Getter
public class Genre {
    private final long id;
    private final String name;
}

对于早期的 Lombok 版本,您必须按如下方式自定义构建器:

@Builder
@Getter
@JsonDeserialize(builder = Genre.GenreBuilder.class)
public class Genre {
    private final long id;
    private final String name;

    @JsonPOJOBuilder(withPrefix = "")
    public static final class GenreBuilder {
    }
}