Java – how to use the builder pattern of an entity with JPA

I read that using the builder pattern is useful when you have a class with many parameters I want to know how to implement an entity using the builder pattern It would be great if you could provide sample code

Solution

Of course, this is possible. You only need to provide a (possibly nested) builder for each entity

This is a working example:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class FluentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String someName;
    private int someNumber;
    private boolean someFlag;

    protected FluentEntity(){}

    private FluentEntity(String someName,int someNumber,boolean someFlag) {
        this.someName = someName;
        this.someNumber = someNumber;
        this.someFlag = someFlag;
    }

    public long getId() {
        return id;
    }

    public String getSomeName() {
        return someName;
    }

    public int getSomeNumber() {
        return someNumber;
    }

    public boolean isSomeFlag() {
        return someFlag;
    }

    public static FluentEntityBuilder builder() {
        return new FluentEntityBuilder();
    }

    public static class FluentEntityBuilder {

        private String someName;
        private int someNumber;
        private boolean someFlag;

        public FluentEntityBuilder setSomeName(final String someName) {
            this.someName = someName;
            return this;
        }

        public FluentEntityBuilder setSomeNumber(final int someNumber) {
            this.someNumber = someNumber;
            return this;
        }

        public FluentEntityBuilder setSomeFlag(final boolean someFlag) {
            this.someFlag = someFlag;
            return this;
        }

        public FluentEntity build() {
            return new FluentEntity(someName,someNumber,someFlag);
        }

    }

}

The code to use it is as follows:

FluentEntity entity = FluentEntity.builder().setSomeName(someName).setSomeNumber(someNumber)
                .setSomeFlag(someFlag).build();

Remember, if you have some, you must exclude automatically generated fields, such as primary keys (ID in this case)

If you want to get rid of the "template" code for creating builder classes for each entity, I would recommend a convenience library, such as Lombok Then, you'll get your builders (or even more) by annotating your entries, perhaps with some extra work to exclude the ID field

You should see project Lombok

However, here is some code to test the builder (implemented using spring boot and Hibernate)

Repository:

import org.springframework.data.repository.CrudRepository;

import com.example.model.FluentEntity;

public interface FluentEntityRepository extends CrudRepository<FluentEntity,Long> {

}

Here are some tests:

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;

import java.util.stream.StreamSupport;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import com.example.model.FluentEntity;

@RunWith(SpringRunner.class)
@Transactional
@SpringBootTest
public class FluentEntityRepositoryTests {

    @Autowired
    private FluentEntityRepository fluentEntityRepository;

    @Test
    public void insertAndReceiveFluentEntityCreatedWithBuilder() {
        final String someName = "name";
        final int someNumber = 1;
        final boolean someFlag = true;

        FluentEntity entity = FluentEntity.builder().setSomeName(someName).setSomeNumber(someNumber)
                .setSomeFlag(someFlag).build();

        entity = fluentEntityRepository.save(entity);
        assertThat("Entity did not get an generated Id!",entity.getId(),greaterThan(-1L));
        assertThat("Entity name did not match!",entity.getSomeName(),is(someName));
        assertThat("Entity number did not match!",entity.getSomeNumber(),is(someNumber));
        assertThat("Entity flag did not match!",entity.isSomeFlag(),is(someFlag));
    }

    @Test
    public void insertSomeAndReceiveFirst() {
        fluentEntityRepository.save(FluentEntity.builder().setSomeName("A").setSomeNumber(1).setSomeFlag(true).build());
        fluentEntityRepository
                .save(FluentEntity.builder().setSomeName("B").setSomeNumber(2).setSomeFlag(false).build());
        fluentEntityRepository.save(FluentEntity.builder().setSomeName("C").setSomeNumber(3).setSomeFlag(true).build());

        final Iterable<FluentEntity> findAll = fluentEntityRepository.findAll();
        assertThat("Should get some iterable!",findAll,notNullValue());

        final FluentEntity fluentEntity = StreamSupport.stream(findAll.spliterator(),false).findFirst().get();
        assertThat("Should get some entity!",fluentEntity,notNullValue());
    }

}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>