I think that this is subjective and depends on your design.
Mostly though this appears to be a design that comes from an active record. In an active record your entity has methods to do database operations and therefore must also know it's database identifier.
When using other patterns such as a repository with a data mapper storing this data in the object becomes unnecessary and perhaps inappropriate.
Take for example a Person
object. I am given a name which may or may not be unique within a family. As the population has grown larger names are no longer unique and so we have come up with surrogate identifiers for increasingly large system. Examples of these include: my drivers license, and social security number. I am not born assigned an id, all of these id's must be applied for.
Most of these do not make good primary keys/ids for software, as they are not universal. At least not outside of their specific system, obviously an SSN is unique, and consistent, to the Social Security Administration. Since we are not generally the providers of this information you would not call them an id
but rather the data they represent, e.g. SSN
. Sometimes even contain the full composed object such as a DriversLicense
which could contain all of the information the driver's license does.
All general id's are thus surrogate keys in the system, and could be replaced with in memory references, only containing id's to make looking up and persisting records easier.
Since an id
is not a piece of conceptual data, I doubt that it (generally) belongs within the object, as it does not come from the domain. Rather it should be retained to its purpose which is to identify an object which has no other way to represent a unique identity. This could be done in a repository/collection with easy.
In software if you need to represent the object as a list, or persist it, you can simply do so from the repository/collection object, or some other object associated with that. When passing on to the Data Mapper (if it's separate), you can simply pass .update( id, obj )
.
Disclaimer: I have not yet tried to build a system that does not contain the id within the entity and thus may prove myself wrong.