1

I have class

public class Order {
  private LocalDateTime creationDate;
  private Date creationDateAsDate;
 }

The creationDate is an existing field in the Order. The creationDateAsDate is a new field for some functionality.

I need to set and save this new field in all places where I save the old field. Unfortunately, I am working with legacy code, and I have 5 places where creationDate field is set. Now I see 2 solutions:

  1. call creationDateAsDate setter in all places where creationDate setter is called.
  2. call creationDateAsDate setter in the creationDate setter.

I don't like both variants. Can someone answer how to do this? It might be one of my variants, or something else.

Pavel Petrashov
  • 1,073
  • 1
  • 15
  • 34
  • Choice 2 seems the right way but hard to say if you don't share the full code you mention. – Victor Polo De Gyves Montero May 25 '21 at 08:18
  • What you've found is a fundamental problem of setters: they are *meant* to encapsulate data access, but they don't provide any abstraction. Everyone expects `setCreationDate` to only set the creation date, but you create the setter in order to allow other actions (even though 99% of the time it only sets the time). – Joachim Sauer May 25 '21 at 08:21
  • 2
    Is this a `java.util.Date` for a new field? That doesn't make any sense. Also, if it's essentially the same as the old field, why have a field at all? Just add a getter that uses the other field value. – daniu May 25 '21 at 08:21
  • What is the use case for a setter which sets one and not the other? Why does your class have both setters, instead of just one setter which updates both fields? – kaya3 May 25 '21 at 08:24
  • @ Joachim Sauer yes I know. That why I asked the question. We have a field in DB. It has type is created by us. It is a long story. MongoDB + LocalDate. We created our LocalDate(not me but our developers). Now we want to compare date like `greaterThan` and `lessThan`. We decided to create a new field and store date in this field in places where we store old field. – Pavel Petrashov May 25 '21 at 10:49
  • @ daniu https://stackoverflow.com/a/40799188/11926338 – Pavel Petrashov May 25 '21 at 11:15

3 Answers3

2

I would recommend updating both setters which is no wrong (that's the reason they exist) calling a common private method to avoid infinite recursion.

public void setCreationDate(LocalDateTime creationDate) {
    Date creationDateAsDate = Date.from(creationDate.atZone(ZoneId.systemDefault())
                                                    .toInstant());
    updateDates(creationDate, creationDateAsDate);
}
public void setCreationDateAsDate(Date creationDateAsDate) {
    LocalDateTime creationDate = LocalDateTime.ofInstant(
            creationDateAsDate.toInstant(), 
            ZoneId.systemDefault());
    updateDates(creationDate, creationDateAsDate);
}
private void updateDates(LocalDateTime creationDate, Date creationDateAsDate) {
    this.creationDate = creationDate;
    this.creationDateAsDate = creationDateAsDate;
}
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
0

Since these are private variables remove one of the variables for example private Date creationDateAsDate and the setter for the vaiable.

Implement getter method as follows.

public Date getCreationDateAsDate(){
 // convert the creationDate to date and return.
}

REF: Converting between java.time.LocalDateTime and java.util.Date for converting LocalDateTime to Date

seenukarthi
  • 8,241
  • 10
  • 47
  • 68
0

You could add a third method (e.g. setCreationDateAsDateAndcreationDate) and call it whenever you want both to be updated. (as classes should be open for extension, but closed for modification). Then put both setters in it,

or

you could call the new setter method from setCreationDateAsDate and setCreationDate (where you create the other property within setters, and then call the third setter setCreationDateAsDateAndcreationDate while passing both of dates as arguments to it)

Hooman
  • 114
  • 1
  • 1
  • 12