kar
kar

Reputation: 3651

Invalid definition when using builder to map an object

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

Upvotes: 1

Views: 419

Answers (2)

Jan Rieke
Jan Rieke

Reputation: 8082

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

Upvotes: 1

Chayne P. S.
Chayne P. S.

Reputation: 1638

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.

Upvotes: 0

Related Questions