Even for just plain data values, getters and setters can be decorated with annotations that modify the member-"property's" behavior depending on context, e.g., what should happen to this member when I serialize to JSON ... or when I read from a DB?
I've found these decorators real useful in the past ... and while they balloon the code for the "data class" itself, they eliminate a lot of code elsewhere.
E.g., this may violate some "separation of concerns", but often one will want to: (a) read some hierarchical data from JSON in a web service request; (b) persist these elements to DB, maintaining proper relations between entities read in from JSON but now persisted as rows to multiple tables in a DB; (c) at some later point read back some of those elements and reconstruct the hierarchy and perhaps transform it or merge it with other hierarchies; (d) perhaps re-persist it, or send it out as a JSON response ... so ...
... in such a situation I am dealing with the same small set of "data classes" everywhere -- but when persisting or reading from a DB I have data fields that represent "primary" or "foreign key" DB values -- I possibly don't want those field values to ever get written to JSON; other member fields deal with the semantic hierarchy of that data in the JSON-like or internal-Java view (e.g., lists, maps, pointers-to-parents-in-hierarchies) ... but I don't want those members ever to be written to the DB (since they're replaced by PK/FK references) ... >>> rather than maintaining two sets of data classes for the two alternative representations (and the ugly boilerplate required to translate between them), it's much easier to have just one set of semantic data classes that each knows how to live in each context (DB, JSON, in-memory, etc. ...). The key to telling these data classes and their members to behave differently, in Java, for each context (JSON deserialize vs JSON serialize vs DB read vs DB write), is to use decorators on their setters and getters.
EDIT: included more lengthy rationale.