3

This error occurs when objectMapper.convertValue(cityEntity, City.class)) is called.

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Builder class com.example.PostgresApp.dto.City$Builder does not have build method (name: 'build')

package com.example.PostgresApp.dto;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.*;
import org.apache.commons.lang3.StringUtils;


@Value
@Builder(builderClassName = "Builder")
@JsonDeserialize(builder = City.Builder.class)
public class City {

    String name;

    String description;

    @JsonPOJOBuilder(withPrefix = StringUtils.EMPTY)
    public static class Builder {

    }
}

Service calling repo seems to be where the exception is thrown

    public List<City> getCities(){
        return cityRepo.findAll().stream().map(cityEntity -> objectMapper
                .convertValue(cityEntity, City.class))
                .collect(Collectors.toList());
    }
Clancinio
  • 734
  • 6
  • 21
  • 40
  • 1
    Lombok is very sensible in relation with these deserialize with builder configurations. Try with `@Jacksonized` annotation, removing @JsonDeserialize(builder = City.Builder.class) and removing @JsonPOJOBuilder annotated statis class. This way Lombok will manage these configurations automagically. – spekdrum Oct 28 '21 at 06:33

2 Answers2

2

The problem is that Jackson cannot deserialize the object value.

My solution was to add the following annotations to my class:

// constructor with no args
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
// constructor with all args
@AllArgsConstructor
// ignore unknown properties during deserialization
@JsonIgnoreProperties(ignoreUnknown = true)

My class ended up looking like this:

@Getter
@Builder
@NoArgsConstructor(force = true, access = AccessLevel.PRIVATE)
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyClass {
    private boolean flag;
    private boolean flag2;
    private MyClassA objectA;
    private MyClassB objectB;
}

If you want to read more on why should we use @NoArgsConstructor and @AllArgsConstructor together, here is a good answer.

chris
  • 2,490
  • 4
  • 32
  • 56
1

Are You sure You always pass name and description to the class Builder?

I got the same error and In my case I was trying to to use a generated Builder to create an Object but I did not pass all of the arguments, so the generated method was not the one spring was looking for. It was searching the N+1 arguments method, but I was passing only N arguments. In this case it will look for a different method signature that can not find.

Prus
  • 23
  • 6