在使用构建器映射对象时出现无效的定义。

huangapple go评论72阅读模式
英文:

Invalid definition when using builder to map an object

问题

我正在使用Spring的Rest Template进行REST调用。

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

但是,如果我使用了Builder模式,就会出现InvalidDefinitionException错误。

如果我按照错误提示添加构造函数,确实可以解决问题。

但是我想避免这样做。我只想将字段设为final,然后让Builder处理构造。

请问我如何解决这个问题,或者这是预期的结果,不能仅使用Builder,确实需要构造函数?谢谢。

以下代码在编译时没有问题,但是在进行REST调用时会出错:

> InvalidDefinitionException: 无法构造my.package.Genre的实例(没有像默认构造函数一样的创建者存在):无法从对象值进行反序列化

@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;
    }
}
英文:

I am making a rest call in Spring via Rest Template.

If the Object I am using to map uses Lombok's Getter/Setter, everything works fine.

But if I use a Builder, it breaks with an InvalidDefinitionException error.

If I follow as per the error and add constructors, it does work.

But I am trying to avoid it. I just want to make the fields final and let builder handle the construction.

Could I get some advice as to how I can get around this or if this is expected and can't simply stick to using just Builder and do need the constructors? Thanks.

The following compiles fine, but when I make the rest call, breaks with following error:

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

The rest call which fails

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

The following will pass when using a Setter. Using the same rest call above to test.

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

Or the following works too if I add constructors which am trying not to do.

If this is a must, I would opt to sticking with a Setter. Do advice.

@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;
    }
}

答案1

得分: 1

从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 {
    }
}
英文:

Starting with Lombok 1.18.16, you can use @Jacksonized to automatically generate everything Jackson needs to use a Lombok @(Super)Builder:

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

For earlier Lombok versions, you have to customize your builder as follows:

@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 {
    }
}

答案2

得分: 0

这应该可以工作。

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

简而言之:@Builder会在没有定义其他构造函数时隐式创建全参构造函数。编译器通常会自动添加无参构造函数,但不会添加。在这种情况下,RestTemplate需要无参构造函数。因此我们添加一个。

英文:

This should work.

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

TDLR; @Builder implicitly create all-args-constructor, if there is no other constructors defined. No-arg-constructor which normally automatically added by compiler won't get added. In this case, RestTemplate need no-arg-constructor.So we add one.

huangapple
  • 本文由 发表于 2020年10月22日 23:57:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64486033.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定