0

A user has a user type and these user types are stored in a database with their own attributes and some id to reference it into the user table.

case class User(id: Int, userType: Int, firstName: String, lastName: String)
case class UserType(id: Int, name: String)

Also I have an aggregation object.

case class User(userData: User, userType: UserType)

Application managers can create their own user types and assign them to the different application users.

Additional information: These user types cannot be modified once created, but could be deleted after passing some validations.

Should the user type be an entity (because it needs to be stored with some id) or be a value object (because two user types with the same values, except the id, are in fact the same object)?

EDIT

Application managers can create their own user types so UserType needs to have its own repository, that's clear. User repository can have just the reference of user type instead of having the user type itself, but the question is if the user type can be treated as an entity or a value object.

  • 1
    Why do they have an `id` if they cannot be modified? Can't their name be their `id`? In that case it would be obvious that they are values. If it is because you may want to change these names and have the change reflect on all users then a `UserType` is an entity. – plalx Oct 19 '16 at 16:25
  • The error was to have thought that the id was the PK instead of the name. Whitout the id and using the name as PK, as you have said, I understand that the user type is a value object. I've used the id as PK mainly because I tend to write all PK of all tables with a numeric type, reading this document [link](http://database-programmer.blogspot.com.es/2008/01/database-skills-sane-approach-to.html#rule1) I've learn the correct way. – CapitanCachopo Oct 19 '16 at 21:18
  • 1
    Nothing prevents you from having a surrogate identity from the persistence perspective. In that case you would hide this ID in an IdentifiedValueObject layer supertype so that your domain model is not aware of it. – plalx Oct 19 '16 at 21:54
  • Possible duplicate of [Should lookup values be modeled as aggregate roots?](http://stackoverflow.com/questions/12870650/should-lookup-values-be-modeled-as-aggregate-roots) – guillaume31 Oct 20 '16 at 10:43
  • @CapitanCachopo if the logic around users and user types is simple and CRUDish enough, I would consider placing them in a separate Bounded Context that doesn't use the DDD tactical patterns (Entity, Aggregate, Repository, etc.) – guillaume31 Oct 20 '16 at 10:50
  • @guillaume31 Would you use an enum or something similar if the set of values is fixed? – plalx Oct 20 '16 at 13:37
  • Probably, but here "Application managers can create their own user types", right? – guillaume31 Oct 20 '16 at 13:38
  • Yep, creating an enum is not possible because those rows could be created manually by application managers. – CapitanCachopo Oct 21 '16 at 10:44
  • @guillaume31 I think is not the same question you mentioned. I have added more information into my question. – CapitanCachopo Oct 21 '16 at 11:01

2 Answers2

1

I think that both.

In the context of "User Management" you create or modify a User using a userType VO that can not be chaged. Create a User and ask for a userType (VO) in cosntructor or use aggregate/entity function to modify user type. i.e.: User.ChangeType(userTypeVO).

When you are in i.e.: "YourSystem Configuration Context" you should treat UserType as entity becasue you have to reference it to delete, modify (fix a spelling error maybe?) or create new userTypes.

jlvaquero
  • 8,571
  • 1
  • 29
  • 45
1

I think your question comes from persistence concerns rather than from the business domain. Is there any sense in having two user types with the same name, but different ids? If the answer is "no" then this is definitely a Value Object.

Vladik
  • 176
  • 1
  • 7