Domain-Driven Design
> >
HowDoYouModelOrHandlePKFKRelationshipsInAnEntity

Tue Jan 13, 2004 11:55 am

Lets say I have a "User" entity. This entity has only "userId"
and "roleId" attributes. The "role" attribute corresponds to a list
of roles in a database table. This table contains only a "ROLE_ID"
and a "ROLE_VALUE".

If a User is modeled to only hold the "roleId", who is responsible
for obtaining the "ROLE_VALUE"? A repository?

Because a Role has an Id in the database, would you model this as
another entity and make this Role entity an attribute of User
instead?

Regards,
Joshua



You'd have User and Role classes in Java (or other OOPL). Both would have "id"
instance variables. Role would have a "value" instance variable. It sounds
like in your scenario Role is "reference data" and a User can only have one
Role. Therefore User would have an instance variable to refer to its Role, but
not vice versa. Furthermore, under that assumption, User is an Entity, Role is
a Value Object, and User aggregates Role.

You'd then have a UserRepository with methods for finding Users by ID or
whatever. Given the assumptions, by Eric's rules, you wouldn't have a Role
repository since Role is a Value Object aggregated by the User Entity. Instead,
the User-finding methods on UserRepository would query both tables, instantiate
both classes, bind the Role into the User, and return a fully-initialized User
aggregate.

RandyStafford


Randy,

Your explanation makes sense. I am still having trouble determining
when something is an entity or a value object. Is Role really a
Value Object even though it has its own Id? In this case, how would
you differentiate each?

Joshua


> Randy,
>
> Your explanation makes sense. I am still having trouble determining
> when something is an entity or a value object. Is Role really a
> Value Object even though it has its own Id? In this case, how would
> you differentiate each?

Does Role /need/ an ID? I am imagining a two-column table (id, name),
and wondering why not just use 'name' as the PK for the ROLE table?

I have worked on a couple of applications now where we have avoided
using the database to store the allowable values of a type-safe enum. I
haven't missed it. That's just one man's experience.

JBRainsberger


Yes, I was thinking the same thing.

EricEvans


Thanks, I appreciate the explanation.

How is this distinction transferred into your code? Do you use some
sort of Naming convention to mark Value Objects from Entities. Do
you use interfaces to "tag" them (ex Serializable)?

Joshua


> Thanks, I appreciate the explanation.
>
> How is this distinction transferred into your code? Do you use some
> sort of Naming convention to mark Value Objects from Entities. Do
> you use interfaces to "tag" them (ex Serializable)?

Only by coincidence. In my last project, I decided to experiment with
storing Value Objects as thin Map wrappers similar in concept to
DynaBeans. There were times when I really liked it (transfering data
from the web layer to the domain layer) and times when I really disliked
it (forgetting to update Value Object descriptors when I added a new
field -- good thing I had tests!). All in all, I'm still searching for a
better way.

Otherwise, I don't see the motivation for making the distinction
explicit in the code. I suppose the difference will be in how they are
used. One would typically not retrieve a Value Object directly from a
Repository, but only through asking an Entity for one of its values, I
guess....

JBRainsberger



I don't have much to add to Randy's explanation. But the entity/value
distinction is not just a matter of whether there is an id field in the
database.

In this case, the id of Role is just a technical artifact. You need it to
create the association in the relational database. If you were working with
in-memory objects, you would just let the User hold a collection of Role
objects (or Role Values), and they would not need to have an id. If there
were only one Role per User, you could put the Role Value as a column in the
User table, dispensing with the id. If the Role Value table had a foreign
key field of User_Id, again we could dispense with the Role id. So that id
is just a technical means of establishing the reference between the two
objects.

On the other hand, even an in-memory version would need some way to
distinguish one User from another and probably search for them. Some
identity is fundamental to that object's meaning.

I would like for my O-R mapping framework to be smart enough for me to
specify how to handle an association such as the Role's id field so that the
collection of Roles would be instantiated automatically when I instantiate a
User (or lazy instantiated, if I so choose).

EricEvans


I think the key question (that distinguishes whether Role is an Entity or a
Value Object) is whether you ever expect anything about the role to *change*.
For example, do you ever expect to update the "value" column in the Role table
for some ID? If so, then it's possible that Role has a life of its own. If
not, it's definitely a Value Object. Reference data. As Mr. Rainsberger
pointed out, a separate table may not even be justified, especially if there are
no other SQL-level clients of that table.

RandyStafford


joshua,

is it possible that your mixing up DDD lingo with database schema lingo ? the
DDD ENTITY is not the same as a database schema entity.

from the way you're describing your model, it sounds like your thinking in
terms of database schemas and building a domain model around it.

MarkRim


Mark,

In the database world, Entity = Table. I know this
mapping/translation is not necessarily true in the OO/DDD world.

Eric's book defines an Entity as an object defined primarily by its
identity. On the other hand, he defines a Value Object as an object
that represents a descriptive aspect of the domain with no
conceptual identity. In fact, he explains that value object should
not be given an identity.

Using the example mentioned earlier, if I change a Users role
from "System Admin" to "Power User", how do I map this change to my
rdbms if I do not maintain that "System Admin" has a role_id of 1
and "Power User" has a role_id of 2?

Joshua


> ... if I change a Users role from "System Admin" to "Power User" ...

This kind of domain language should drive your design, rather than
existing database implementations. (Easy for me to say) However,
probably the existing database design is a fossil of some previous
discussion about the domain. Sounds like you are in the field of
reverse domain engineering. :-)

Regarding your question, assuming that this is some kind of Windows
NT authorizing domain, it seems like Role should be an entity class.
Roles can be shared by many Users. The fact that you named the roles
distinctively also indicates that they are more than values.

Btw. this might be another test for telling entity and value objects
apart. When you delete your User, should the Role be deleted also?
Yes=Role is a value object, No=Role is an entity object.

JohanNilsson


> Using the example mentioned earlier, if I change a Users role
> from "System Admin" to "Power User", how do I map this change to my
> rdbms if I do not maintain that "System Admin" has a role_id of 1
> and "Power User" has a role_id of 2?

Set user.role to "admin" or "power".

JBRainsberger



HowDoYouModelOrHandlePKFKRelationshipsInAnEntity is mentioned on: ThreadView


VeryQuickWiki Version 2.6.3 - HTML Export