tags:

views:

164

answers:

6

I am creating the model for a web application. The tables have ID fields as primary keys. My question is whether one should define ID as a property of the class?

I am divided on the issue because it is not clear to me whether I should treat the object as a representation of the table structure or whether I should regard the table as a means to persist the object.

If I take the former route then ID becomes a property because it is part of the structure of the database table, however if I take the latter approach then ID could be viewed as a peice of metadata belonging to the database which is not strictly a part of the objects model.

And then we arrive at the middle ground. While the ID is not really a part of the object I'm trying to model, I do realise that the the objects are retrieved from and persisted to the database, and that the ID of an object in the database is critical to many operations of the system so it might be advantageous to include it to ease interactions where an ID is used.

I'm a solo developer, so I'd really like some other, probably more experienced perspectives on the issue

+7  A: 

Basically: yes. All the persistence frameworks ive used (including Hibernate, Ibatis) do require the ID to be on the Object.

I understand your point about metadata, but an Object from a database should really derive its identity in the same way the database does - usually an int primary key. Then Object-level equality should be derived from that.

Sometimes you have primary keys that are composite, e.g first name and last name (don't ever do this!), in which cases the primary key doesn't become 'metadata' because it is part of the Object's identity.

I generally reserve the ID column of an object for the database. My opinion is that to use it for any 'customer-facing' purpose, (for example, use the primary key ID as a customer number) you will always shoot yourself in the foot later.

jgubby
Your last point is really just good database design. A (primary) key should *never* have any other meaning. Any meaningful data has the possibility of changing and, if it's a key, you're just asking for problems if and when it does. This doesn't mean it can't be exposed to users, but that's still generally best avoided, as most people will find "jgubby" much easier to remember than "user id 69573".
Dave Sherohman
+1, since that is actually my user id.
jgubby
+5  A: 

If you ever make changes to the existing data (instead of exclusively adding new data), you need the PK. Otherwise you don't know which record to change in the DB.

balpha
I keep adding my answers a few minutes after you... wierd :). But good answers!
Jeff Meatball Yang
That is a point I hadn't fully considered, at the moment we won't be allowibg any content editing, however this is one of those things that seams appropriate to add now rather than wish I had added later when I do need it
Crippledsmurf
+1  A: 

I include the ID as a property. Having a simple unique identifier for an object is often very handy regardless of whether the object is persisted in a database or not. It also makes your database queries much more simple.

I would say that the table is just a means to persist an object, but that doesn't mean the object can't have an ID.

AndrewS
+2  A: 

You should have the ID in the object. It is essential.

The easiest use case to give as an example is testing equality:

public bool Equals(Object a, Object b) {  return {a.ID = b.ID}; }

Anything else is subject to errors, and you'll find that out when you start getting primary key violations or start overwriting existing data.

By counterargument:

Say you don't have the ID in the object. Once you change an object, and don't have it's ID from the database, how will you know which record to update?


At the same time, you should note that the operations I mention are really private to the object instance, so ID does not necessarily have to be a public property.

Jeff Meatball Yang
+1  A: 

I'm very much of the mindset that the table is a means to persist the object, but, even so, I always expose the IDs on my objects for two primary reasons:

  1. The database ID is the most convenient way to uniquely identify an object, either within a class (if you're using a per-table serial/autonumber ID) or universally (if you're maintaining a separate "ID-to-class" mapping). In the context of web applications, it makes everything much simpler and more efficient if your forms are able to just specify <input type=hidden name=id value=12345> instead of having to provide multiple fields which collectively contain sufficient information to identify the target object (or, worse, use some scheme to concatenate enough identifying information into a single string, then break it back down when the form is submitted).

  2. It needs to have an ID anyhow in order to maintain a sane database structure and there's no reason not to expose it.

Dave Sherohman
My reason not to expose it was the argument that the ID is metadata and not really a part of the object in the literal sense.However having read the responses here I realise that this opinion is somewhat short-sighted because it fails to account for the neccessary relationship between the database and the object.
Crippledsmurf
+1  A: 

Should the ID in the object read-only or not? In my mind it should be read-only as by definition the ID will never change (as it uniquely identifies a record in the database).
This creates a problem when you create a new object (ID not set yet), save it in the database through a stored procedure which returns the newly created ID then how do you store it back in the object if the ID property is read-only?

Example:
Employee employee = new Employee();
employee.FirstName="John";
employee.LastName="Smith";

EmployeeDAL.Save(employee);

How does the Save method (which actually connects to the database to save the new employee) update the EmployeeId property in the Employee object if this property is read-only (which should be as the EmployeeId will never ever change once it's created).

Anthony
This is almost a seperate question in it's own right. In answer to whether the ID property should be read-only, in general I believe it should for the reasons you stated. The property can be read-only and the DAL may actually create another object based on the one passed, or possibly use reflection to alter the value, depending on the DAL
Crippledsmurf
Creating another object would work but that seems wrong to me. Say your object has 50 properties. In this case you would create a new one and copy the values of all the properties just so you can also update the ID field.In my mind the DAL should have write access to the ID field to update it but the ID field should be read-only for the rest of the world. This is a bit tricky to implement if the the class the object is based on and the DAL are in 2 separate assemblies (as they should be).
Anthony