Domain data classes with fluid property lists
Is it fine for your data models to have a sort of "open-ended" list of properties? For example, you may have some Employee: // getters, setters, annotations are omitted public class Employee { private final String name; private final String lastName; private final String departmentId; } It may have a list of hard-coded properties as well as a special "magic" method called: private final Map additionalProperties = new HashMap(); // ... public Object getProperty(String propertyName) { return additionalProperties.get(propertyName); } It may come in handy if your schemas are fluid. Anytime anyone can throw in an additional key-value pair into a DB procedure you call, and you as a developer don't feel like updating your entity/DTO classes each time it happens (especially, as the extra property may "fly by night"). So you make your data classes that correspond to DB-returned key-value pair groupings have a special map of any properties that don't match any of the hardcoded fields. Then you provide a public accessor that queries the map in case there's a need (probably, an ad-hoc need) to process an additional property. The term "additional properties" refers to those properties that are not tightly coupled with a given domain model and yet, at least somewhere, returned by a database along with the model's intrinsic properties. Additional properties are likely to be properties of associated entities. In my case, it could be departmentName, for example. They could also be calculated or derived values. Is it an acceptable way of dealing with the kind of situation I described? There's an alternative that I mentioned here (it's the approach I currently use): to keep your entities nice and tight but provide a wrapper type that can extend your data class with additional values: public class ExtendedEntity { private final T entity; private final Map additionalProperties; private ExtendedEntity(T entity, Map additionalProperties) { this.entity = entity; this.additionalProperties = additionalProperties; } public ExtendedEntity of(T entity, Map additionalProperties) { return new ExtendedEntity(entity, additionalProperties); } @Override public T getEntity() { return entity; } public Object getAdditionalValue(String propertyName) { return additionalProperties.get(propertyName); } } I'm not as sure about my choice anymore, though. Any time someone adds just one extra property, you have to change the entire data type (e.g. from Employee to ExtendedEntity). It may affect DAOs, services, clients of those services, etc. Maybe, we should keep all the extra properties inside entities themselves (if any are present). What do you think?

Is it fine for your data models to have a sort of "open-ended" list of properties?
For example, you may have some Employee
:
// getters, setters, annotations are omitted
public class Employee {
private final String name;
private final String lastName;
private final String departmentId;
}
It may have a list of hard-coded properties as well as a special "magic" method called:
private final Map additionalProperties = new HashMap<>();
// ...
public Object getProperty(String propertyName) {
return additionalProperties.get(propertyName);
}
It may come in handy if your schemas are fluid. Anytime anyone can throw in an additional key-value pair into a DB procedure you call, and you as a developer don't feel like updating your entity/DTO classes each time it happens (especially, as the extra property may "fly by night"). So you make your data classes that correspond to DB-returned key-value pair groupings have a special map of any properties that don't match any of the hardcoded fields. Then you provide a public accessor that queries the map in case there's a need (probably, an ad-hoc need) to process an additional property.
The term "additional properties" refers to those properties that are not tightly coupled with a given domain model and yet, at least somewhere, returned by a database along with the model's intrinsic properties. Additional properties are likely to be properties of associated entities. In my case, it could be departmentName
, for example. They could also be calculated or derived values.
Is it an acceptable way of dealing with the kind of situation I described?
There's an alternative that I mentioned here (it's the approach I currently use): to keep your entities nice and tight but provide a wrapper type that can extend your data class with additional values:
public class ExtendedEntity {
private final T entity;
private final Map additionalProperties;
private ExtendedEntity(T entity, Map additionalProperties) {
this.entity = entity;
this.additionalProperties = additionalProperties;
}
public ExtendedEntity of(T entity, Map additionalProperties) {
return new ExtendedEntity<>(entity, additionalProperties);
}
@Override
public T getEntity() {
return entity;
}
public Object getAdditionalValue(String propertyName) {
return additionalProperties.get(propertyName);
}
}
I'm not as sure about my choice anymore, though. Any time someone adds just one extra property, you have to change the entire data type (e.g. from Employee
to ExtendedEntity
). It may affect DAOs, services, clients of those services, etc. Maybe, we should keep all the extra properties inside entities themselves (if any are present).
What do you think?