Hammerspace
Hammerspace

Reputation: 93

How to create an object via forms using the builder pattern?

Entity with nested builder:

@Entity
@Table(name="food")
public class Food {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(name="name")
    private String name;

    @Column(name="type")
    private String type;

    @Column(name="description")
    private String description;

    @Column(name="date")
    private LocalDate expiration;

    @ManyToOne
    @JoinColumn(name="container_id", foreignKey = @ForeignKey(name = "FK_FOOD"))
    private Container container;

    private Food(FoodBuilder foodbuilder) {
        this.name = foodbuilder.name;
        this.type = foodbuilder.type;
        this.description = foodbuilder.description;
        this.expiration = foodbuilder.expiration;
    }

    //getters omitted for brevity

    public static class FoodBuilder {
        private String name;    
        private String type;
        private String description;
        private LocalDate expiration;


        public FoodBuilder(String name) {
            this.name = name;
        }

        public FoodBuilder setType(String type) {
            this.type = type;
            return this;
        }

        public FoodBuilder setDescription(String description) {
            this.description = description;
            return this;
        }

        public FoodBuilder setExpiration(LocalDate expiration) {
            this.expiration = expiration;
            return this;
        }

        public Food buildFood(){
            return new Food(this);
        }
    }
}

I know how to use the main method to create a new object with the builder pattern i.e.

Food food = new Food.FoodBuilder...setters...build()

but I have been unable to find how I can use this pattern to create an object when I submit info via a form on the front-end to my api.

Upvotes: 2

Views: 208

Answers (3)

Saurabh Bhurle
Saurabh Bhurle

Reputation: 169

If you designed you front end using JSP, use spring form tag by importing spring form taglib. Your controller level you can get Whole object by using @ModelAttribute. Spring take care of nested object only when all the POJO need to be stand.

Upvotes: 2

Hammerspace
Hammerspace

Reputation: 93

Working code (added @JsonDeserialize, @JsonPOJOBuilder, @JsonCreator, and @JsonProperty):

@Entity
@Table(name="food")
@JsonDeserialize(builder = Food.FoodBuilder.class)
public class Food {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;

    @Column(name="name")
    private String name;

    @Column(name="type")
    private String type;

    @Column(name="description")
    private String description;

    @Column(name="date")
    private LocalDate expiration;

    @ManyToOne
    @JoinColumn(name="container_id", foreignKey = @ForeignKey(name = "FK_FOOD"))
    private Container container;

    private Food(FoodBuilder foodbuilder) {
        this.name = foodbuilder.name;
        this.type = foodbuilder.type;
        this.description = foodbuilder.description;
        this.expiration = foodbuilder.expiration;
    }

    //getters omitted for brevity

    @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "set")
    public static class FoodBuilder {
        private String name;    
        private String type;
        private String description;
        private LocalDate expiration;

        @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
        public FoodBuilder(@JsonProperty("name") String name) {
            this.name = name;
        }

        public FoodBuilder setType(String type) {
            this.type = type;
            return this;
        }

        public FoodBuilder setDescription(String description) {
            this.description = description;
            return this;
        }

        public FoodBuilder setExpiration(LocalDate expiration) {
            this.expiration = expiration;
            return this;
        }

        public Food buildFood(){
            return new Food(this);
        }
    }
}

Upvotes: 1

Blake
Blake

Reputation: 1327

I will assume your api call is sending a serialized Food object, which is then received by a controller. If you're trying to deserialize this data into an instance by specifically using the given builder, jackson should be able to do this for you via the JsonDeserialize annotation by providing a builder argument.

Upvotes: 2

Related Questions