javajsonspring-bootdate-parsing

Why DOB logging every time whether updated or not during update API in Java?


I am logging fields which will be update during update API call. But getting DOB field every time whether it is updating or not

DOB is of Date type

private Date DOB;

Logging DOB VALUE when passing this in payload { "DOB": "1990-01-01"}

dob: Mon Jan 01 05:30:00 IST 1990
Updated Fields during request: DOB  

is it because it has time also? Though I'm getting same time on every request, still, it is printing that DOB is updated even when value was same and not updated. Why so?

And if I am passing DOB in payload (postman) like this:

 "DOB": "20101212"

//it is printing only this 1970 value on log console
dob: Thu Jan 01 11:05:01 IST 1970 

How can I handle these situations?

Code

public static class Updater {
  private final OrgEmployeeMap existing;
  private final EmployeeInformation information;
  private final Set<String> updatedFields = new HashSet<>();

  public Updater(OrgEmployeeMap existing, EmployeeInformation information) {
    this.existing = existing;
    this.information = information;
  }

  public <T> Updater update(String fieldName,
                            Function<EmployeeInformation, T> newValueGetter,
                            Function<OrgEmployeeMap, T> oldValueGetter,
                            BiConsumer<OrgEmployeeMap, T> oldValueSetter) {
    final var newValue = newValueGetter.apply(information);
    final var oldValue = oldValueGetter.apply(existing);
    if (newValue == null || newValue.equals(oldValue)) {
      return this;
    }
    this.updatedFields.add(fieldName);
    oldValueSetter.accept(existing, newValue);
    return this;
  }

  public Set<String> getUpdatedFields() {
    return updatedFields;
  }
}
private void updateExistingEmployee(OrgEmployeeMap existingOrgEmployee, RequestMessage requestMessage) {
    try {
        EmployeeInformation employeeInfo = requestMessage.getData().get(0).getDemographicData().getEmployeeInformation().get(0);
        final var updater = new Updater(existingOrgEmployee, employeeInfo);

        updater
            .update("FirstName", EmployeeInformation::getEmployeeFirstName, OrgEmployeeMap::getFirstName, OrgEmployeeMap::setFirstName)
            .update("LastName", EmployeeInformation::getEmployeeLastName, OrgEmployeeMap::getLastName, OrgEmployeeMap::setLastName)
            .update("DOB", EmployeeInformation::getDOB, OrgEmployeeMap::getDob, OrgEmployeeMap::setDob)
            .update("Gender", EmployeeInformation::getGender, OrgEmployeeMap::getGender, OrgEmployeeMap::setGender)
            .update("Email", EmployeeInformation::getEmail, OrgEmployeeMap::getEmail, OrgEmployeeMap::setEmail);

        final var modifiedFields = updater.getUpdatedFields();
        if (!modifiedFields.isEmpty()) {
            log.info("Updated employee : " + String.join(", ", modifiedFields));
        }

        orgEmployeeMapRepository.save(existingOrgEmployee);

        log.info("Updated Employee : " + existingOrgEmployee);
    } catch (JSONException e) {
        log.error("error in processing the request error", e.getMessage());
    } catch (Exception ex) {
        log.error("An unexpected error occurred: " + ex.getMessage(), ex);
    }
}

dto class

@Data
public class EmployeeInformation {

    @JsonProperty(value = "Email")
    private String Email;

    @JsonProperty(value = "EmployeeFirstName")
    private String EmployeeFirstName;

    @JsonProperty(value = "EmployeeLastName")
    private String EmployeeLastName;

    @JsonProperty(value = "DOB")
    private Date DOB;

..
}

model class

@Data
@Entity
@Table(name = "employee")
public class EmployeeMap {
@Id
    @Column(name = "Id", length = 100, nullable = false)
    private String Id;

    @Column(name = "firstName", length = 100, nullable = false)
    private String firstName;

    @Column(name = "lastName", length = 100)
    private String lastName;

    @Column(name = "email", length = 100, nullable = false)
    private String email;

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

    @Column(name = "dob", nullable = false)
    private Date dob;
}

Solution

  • java.time

    The java.util date-time API and their corresponding parsing/formatting type, SimpleDateFormat are outdated and error-prone. In March 2014, the modern Date-Time API supplanted the legacy date-time API. Since then, it has been strongly recommended to switch to java.time, the modern date-time API.

    You can use DateTimeFormatter#BASIC_ISO_DATE (which corresponds to yyyyMMdd pattern) to parse your date string, 20101212 to a LocalDate.

    Demo:

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    
    class Main {
        public static void main(String[] args) {
            System.out.println(LocalDate.parse("20101212", DateTimeFormatter.BASIC_ISO_DATE));
        }
    }
    

    Output:

    2010-12-12
    

    Based on this description, you can make the following changes in your code:

    @JsonProperty(value = "DOB")
    @JsonFormat(pattern = "yyyyMMdd", shape = JsonFormat.Shape.STRING)
    private LocalDate DOB;
    

    Learn about the modern date-time API from Trail: Date Time