0

Similar to this question. I have an interface DateRangeModel:

I use this to automatically validate dates in implementers:

public interface DateRangeModel {

    @ApiModelProperty(value = "From date. Must be less than to date.")
    @Column()
    Date getFromDate();

    void setFromDate(Date date);

    @ApiModelProperty(value = "To date. Must be greater than to date.")
    @Column()
    Date getToDate();

    void setToDate(Date date);


    /**
     * Checks that if both dates are populated, a valid date range is used.
     *
     * @return true if the date is a valid range.
     */
    @AssertTrue(message = "To date must be greater than or equal to from date.")
    @JsonIgnore
    default boolean areDatesValid() {

        if (getToDate() != null && getFromDate() != null) {
            return !getFromDate().after(getToDate());
        }
        return true;
    }
}

I implement it like this:

@EqualsAndHashCode
@Data
@Builder
public class BirthdayParty implements DateRangeModel {

    Date fromDate;
    Date toDate;
    String name;

}

Which compiles and seems to work, but I get that error when running PMD:

Returning a reference to a mutable object value stored in one of the object's fields exposes the internal representation of the object.

How can I either accomplish what I want (an interface with to/from date validation) without having to implement the setDate methods in all implementers (which I think would defeat the purpose)?

Jeff
  • 4,285
  • 15
  • 63
  • 115

1 Answers1

3

The problem is that java.util.Date is mutable and you return it in your getters. So someone could do this:

BirthdayParty party = ...;
Date fromDate = party.getFromDate();
...
Date someDate = fromDate;
...
// you might not be aware that this also changes the fromDate in party
someDate.setTime(12345678);

There are four things you can do:

  1. Disable the PMD rule.
  2. Suppress the warning everywhere you use one of these a classes.
  3. Don't use Lombok and copy the dates in your setters and getters instead of just storing/returning the reference to a date.
  4. Use java.time.ZonedDateTime (or LocalDateTime) instead of Date. ZonedDateTime is immutable and should not lead to this warning.

I suggest the fourth option. Not only because it gets rid of the PMD warning but also because the new time API in Java 8 is so much better and easier to use than java.util.Date.

Acanda
  • 672
  • 5
  • 12