英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论