简体   繁体   中英

Design Pattern to a better update on Spring boot REST API

I have created a REST API using Java with Spring boot, i'm new using Design Patterns but i need to improve my ppdate method to verify all information on my Atlete entity.

My Entity is about atletes informations:

@Getter
@Setter
@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Table(name = "atletes", schema = "personas")
public class Atlete {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_atlete")
    private Long idAtlete;

    @Lob
    @Type(type = "org.hibernate.type.TextType")
    @Column(name = "atlete_name")
    private String atleteName;

    @Temporal(TemporalType.DATE)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    @Column(name = "date_birth")
    private Date dateBirth;

    @Column(name = "atlete_height")
    private Double atleteHeight;

    @Column(name = "atlete_weight")
    private Double atleteWeight;

    @Column(name = "atlete_imc")
    private Double atleteImc;

    @Lob
    @Type(type = "org.hibernate.type.TextType")
    @Column(name = "atlete_bid")
    private String atleteBid;

    @Enumerated(EnumType.STRING)
    @Column(name = "dominant_leg")
    private DominantLeg dominantLeg;

    @Enumerated(EnumType.STRING)
    @Column(name = "position")
    private Position position;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_adress")
    private Adress adress;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_contact")
    private Contact contact;

    @JsonProperty("atleteClubs")
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "atlete", cascade = CascadeType.REMOVE)
    private List<AtleteClub> atleteClubs;

    @Lob
    @Type(type = "org.hibernate.type.TextType")
    @Column(name = "atlete_deceases")
    private String deceases;

My PUT requisition on my AtleteController:

@PutMapping(value = URL_SINGULAR, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<AtleteDTO> updateAtlete(@PathVariable Long id, @RequestBody @Valid AtleteDTO atleteDTO) {
        Optional<Atlete> verifyId = atleteRepository.findById(id);
        if (verifyId.isPresent()) {
            Atlete updatedAtlete = atleteService.desconvertObject(atleteDTO);
            Atlete atlete = atleteService.update(id, updatedAtlete, atleteRepository);
            return ResponseEntity.ok(new AtleteDTO(atlete));
        }
        return ResponseEntity.notFound().build();
    }

On my AtleteService i'm verifying if my variables and objects are updated, like below:

@Transactional
    public Atlete update(Long id, Atlete updated, AtleteRepository atleteRepository) {
        Atlete saved = atleteRepository.findByidAtlete(id);
        if (updated.getAtleteName() != null && !updated.getAtleteName().equals(saved.getAtleteName())) {
            saved.setAtleteName(updated.getAtleteName());
        }
        if (updated.getDateBirth() != null && !updated.getDateBirth().equals(saved.getDateBirth())) {
            saved.setDateBirth(updated.getDateBirth());
        }
        if (updated.getAtleteHeight() != null && !updated.getAtleteHeight().equals(saved.getAtleteHeight())) {
            saved.setAtleteHeight(updated.getAtleteHeight());
        }
        if (updated.getAtleteWeight() != null && !updated.getAtleteWeight().equals(saved.getAtleteWeight())) {
            saved.setAtleteWeight(updated.getAtleteWeight());
        }
        if (updated.getAtleteImc() != null && !updated.getAtleteImc().equals(saved.getAtleteImc())) {
            saved.setAtleteImc(updated.getAtleteImc());
        }
        if (updated.getAtleteBid() != null && !updated.getAtleteBid().equals(saved.getAtleteBid())) {
            saved.setAtleteBid(updated.getAtleteBid());
        }
        if (updated.getDominantLeg() != null && !updated.getDominantLeg().equals(saved.getDominantLeg())) {
            saved.setDominantLeg(updated.getDominantLeg());
        }
        if (updated.getPosition() != null && !updated.getPosition().equals(saved.getPosition())) {
            saved.setPosition(updated.getPosition());
        }
        if (updated.getContact() != null && !updated.getContact().equals(saved.getContact())) {
            saved.setContact(contactService.update(updated.getContact().getId(), updated.getContact(), contactRepository));
        }
        if (updated.getAdress() != null && !updated.getAdress().equals(saved.getAdress())) {
            saved.setAdress(adressService.update(updated.getAdress().getId(), updated.getAdress(), adressRepository));
        }
        if (updated.getAtleteClubs() != null && !updated.getAtleteClubs().isEmpty()) {
            for (AtleteClub atleteClub : updated.getAtleteClubs()) {
                atleteClubService.update(atleteClub.getId(), atleteClub,atleteClubRepository);
            }
        }
        if (updated.getDeceases() != null && !updated.getDeceases().equals(saved.getDeceases())) {
            saved.setDeceases(updated.getDeceases());
        }
        return saved;
}

Is there some Design Pattern or Spring utility to make an update without verifying each variable and object of my Entity? if i have 50 variables i need to verify all of them like that?

I remember I had a similar issue and I used Reflection, it was the easiest way of doing it.

Iterate over the attributed of the first object, and get the exact same attribute of the other object and compare them.

Example:

    public static void main(String[] args) throws IllegalAccessException {
        TestClass testObject1 = new TestClass();
        testObject1.setId(1L);
        testObject1.setName("TestObject1");

        TestClass testObject2 = new TestClass();
        testObject2.setId(2L);
        testObject2.setName("TestObject2");

        for (Field field : testObject1.getClass().getDeclaredFields()) {
            boolean accessibleValue = field.isAccessible();
            field.setAccessible(true);
            Object otherValue = field.get(testObject2);

            if (!field.get(testObject1).equals(otherValue))
                field.set(testObject1, otherValue);

            field.setAccessible(accessibleValue);
        }

        System.out.println(testObject1);
    }

    public static class TestClass {

        private long id;
        private String name;

        public void setId(long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "TestClass{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

Output:

TestClass{id=2, name='TestObject2'}

Perhaps what you need is @DynamicUpdate annotation that provided by the Spring Data JPA.

@DynamicUpdate is a class-level annotation that can be applied to a JPA entity. It ensures that Hibernate uses only the modified columns in the SQL statement that it generates for the update of an entity.

I quoted it directly from the reference link below, please look at the reference link for further details.

Reference link .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM