Should an object know its own ID?

obj.id seems fairly common and also seems to fall within the range of something an object could know about itself. I find myself asking why should my object know its own id?

It doesn’t seem to have a reason to have it? One of the main reason for it existing is retrieve it, and so my repositories need to know it, and thus use it for database interaction.

I also once encountered a problem where I wanted to serialize an object to JSON for a RESTful API where the id did not seem to fit in the payload, but only the URI and including it in the object made that more difficult.

Should an object know it’s own id? why or why not?

update:
Terms

  1. id: Identifier attribute on an object. in database terms, a surrogate key not a natural key.
  2. Object: an Entity, or otherwise uniquely identifiable object within the system.

9

It’s fairly common to include the ID, but it’s also common to use dictionaries, i.e. the data structures where each object is associated with its ID in a way that you can easily retrieve this object knowing the corresponding ID, but the object doesn’t know it.

For example, if you’re creating an API with two methods:

  • http://api.example.com/products/

    Loads the list of IDs of products.

  • http://api.example.com/product/452/

    Loads a product of ID 452.

Then you don’t need to resend the ID 452 in the JSON response of the second request. The user of the API already knows the ID.

In an attempt to leave my answer as abstract as your question, I think you’ve actually answered your own question.

An object should know its own ID if it needs to.

An object shouldn’t know its ID (or that it even has one) if it doesn’t need to.

As you pointed out, there are cases where it is either inconvenient or unnecessary for the object to retain or know if its ID. But there are other cases where it is more convenient for the object to be aware of its ID. Code your objects as appropriate to their usage.

4

Short Answer: Including object identifier within the object is a must if it is going to be referred.

For a scenario where you are planning to use a collection of objects and have plans to refer an individual object/entity then identifier should be included. However, there might be cases where natural key/identifier like DateTime can artificially fulfill that need.

In addition, you may have your DTO‘s as a lightweight container of your object, that may skip/include object identifier in itself. Really all this choices are really depend on your business use cases and needs.

Edit: if you want to identify your object you need to have an identifier. That identifier can be a surrogate Id, date-time, guid, etc… basically, anything that identifies your object from others in a unique way.

4

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.

As GlenH7 noted in a comment, it’s a good question, because it challenges what many people take for granted. My take on it however is that even if leaving the id out might seem conceptually pure, the pragmatic thing to do would be to keep the id with the object across as many layers of the system as possible. It costs little, but can come in handy when things start to break down.

An entity might not need to know it’s id, just like a person doesn’t need to know his personal identification number, driver license number nor any other identifier that might be in use in your location. You could certainly do without it most of the time. It’s wise however to carry some kind of identification on you, just in case.

The same can be said of an object. Regardless of the data access layer’s intricacies, the object ultimately maps to a certain database entry. This entry might only be uniquely identifiable by object’s id. If so, then I would prefer to have this information available to me at any time, regardless whether I’m debugging some UI code, number crunching in the business layer, the repository itself or a dependent system across a webservice. Or whether I’m browsing error logs for that matter.

In your case, if you’re only fetching data from the db and pushing it through the webservice, leaving the id out might be be the right thing to do. I just don’t believe that it makes more sense than keeping it in the general case.

1

You are right, you don’t need to store the id in the object, as long as you only need to know it in your repository context.

The situation changes when you pass the object to code outside that context, code that did not request the object by id (and therefore doesn’t know it yet), but needs the id for whatever purpose (eg. to place it on a list of ids that will be requested from the repository later, by yet another code).

In that situation, you have two options:

  • introduce a new function argument ‘id’ in the whole chain of functions between the repository context and the function where the id is needed

  • include the id in the object

In most of these cases, storing the id inside the object will be the better solution. It will also reduce code changes when the id is needed in unforeseen places, plus it might be helpful with debugging at times.

That’s why I do it when I do it.

1

Because I like real world analogies: It would be decidedly more efficient if people kept their passports (or other identifying documents) on their person, instead of them being stored in some separate location.

The question is how you intend to link them when you need to, if you’re storing them separately. This wouldn’t be a problem if you’re already storing the ID with the object that the ID identifies.

So the question becomes: what benefit are you trying to gain by separate the two; and does it outrank the added complexity and effort of having to handle and deal with a separated ID and identifiable object?


I also once encountered a problem where I wanted to serialize an object to JSON for a RESTful API where the id did not seem to fit in the payload, but only the URI and including it in the object made that more difficult.

This is the part where you have to consider that this particular API chose to have an API model (= without ID) that was different from the underlying domain model (= with ID).

Generally speaking, I’ll advocate against reusing the domain model as the API model. However, if you want to do pure REST (and I mean 100% pure), then yeah you could get away with reusing your domain model. But at the same time, it wouldn’t be the end of the world to include the ID both in the model and in the URL, regardless of whether you reuse your domain model or not.

One of the main reason for it existing is retrieve it, and so my repositories need to know it, and thus use it for database interaction.

You’re glossing over the fact that someone asks the repositories to retrieve them, and that someone obviously needs to know the ID before they are able to ask the repository (directly or indirectly) what resource to retrieve using this ID.

Not providing an ID in a REST resource would cause issues down the line when the URL does not contain the identifier for the resource being returned. For example, /api/author/123/articles would return you a collection of articles written by author 123. But if the article IDs aren’t in the article model themselves, how do you expect the consumer to be able to call any article-specific endpoints?

Adding the ID into the resource makes it significantly easier to track the identifier for a given object, instead of sending the consumer on a magical quest to find the link between a fabled identifier that’s somehow not found with the object that it identifies.

2

An object should probably not know its own ID most of the time.

The object is not identified by itself nor within itself but by some other part of the system and within the system, where it is identified in relation to other objects that might be similar to it.

The key here is that identifying an object implies the existence of other objects that you are distinguishing it from. The context of the Id is not the object but something that contains the object.
So unless you have the common kind of dirty code where the business logic is built on top of the database schema, the object should probably not know its own ID in most cases. The fact that you need it for persistence does not mean that you have to have it inside the object itself, it just needs to be directly related to the object. Your persistence may need it, but not the object for the business logic.

Maybe if the object needs to inform itself directly to others of its ID for some reason, you would need to break this principle, but in general, I think it just makes sense and it will save you from having some messy duplicated indexes(or ids, which are most of the time functionally the same thing). I can’t think of an example of this counter, but I am sure they exist.

My two cents

Two situations when an object should know its own ID:

  1. When ID column (or whatever column is used as ID) happens to also be a business key.
  2. For debudding purposes, so you can inspect the ID.

Something not mentioned in other answers is that whether an object should know its own ID depends on the type of ID.

If the id is sequential (ie 1, 2, 3, …), or otherwise at risk of collisions, then probably no – it shouldn’t know its own ID. This id refers to the object’s position in a collection, and may need to be changed if collections are merged or reindexed for some reason. That means your object will either have to be mutable, or it will become “invalid” after the collection that its ID implicitly referred to has undergone the merge/reindexing.

If the id is random (e.g. a ULID like 01HW8Z5QBGE0JR7TY6KC2XRKVS), then probably yes – it should know its own ID. There is likely no reason you’ll ever have to change this ID – and you don’t have to think of the id as implicitly referring to the collection. A merger of two collections does not require changing IDs, and your object can be immutable.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật