Entities in domain driven design - java

I am reading Eric Evans book about DDD and I have a question to the following quote. How do you make your equals() method when you should not use the attributes? I am using JPA and I have a id attribute which is unique but this is not set until you actually persist the entity. So what do you do? I have implemented the equals method based on the attributes and I understand why you shouldn't because it failed in my project.
Section about entities:
When an object is distinguished by its identity, rather than its
attributes, make this primary to its definition in the model. Keep the
class definition simple and focused on life cycle continuity and
identity. Define a means of distinguishing each object regardless of
its form or history. Be alert to requirements that call for matching
objects by attributes. Define an operation that is guaranteed to
produce a unique result for each object, possibly by attaching a
symbol that is guaranteed unique. This means of identification may
come from the outside, or it may be an arbitrary identifier created by
and for the system, but it must correspond to the identity
distinctions in the model. The model must define what it means to be
the same thing.
http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215

Couple approaches possible:
Use a business key. This is the most 'DDD compliant' approach. Look closely at domain and business requirements. How does your business identify Customers for example? Do they use Social Security Number or phone number? How would your business solve this problem if it was paper-based (no computers)? If there is no natural business key, create surrogate. Choose the business key that is final and use it in equals(). There is a section in DDD book dedicated to this specific problem.
For the cases when there is no natural business key you can generate UUID. This would also have an advantage in distributed system in which case you don't need to rely on centralized (and potentially unavailable) resource like database to generate a new id.
There is also an option to just rely on default equals() for entity classes. It would compare two memory locations and it is enough in most cases because Unit Of Work (Hibernate Session) holds on to all the entities (this ORM pattern is called Identity Map). This is not reliable because it will break if you use entities that are not limited to the scope of one Hibernate Session (think threads, detached entities etc)
Interestingly enough, 'official' DDD sample uses a very lightweight framework where every entity class is derived from Entity interface with one method:
boolean sameIdentityAs(T other)
// Entities compare by identity, not by attributes.

If the object is not persistent yet, then is there any harm in comparing 2 objects based on their attributes?
I am not sure why this failed in your project, but in my experience, comparison based on attributes almost always is slippery slope if your attributes are not final. That means, 2 objects that are equal now, may not be equal after sometime. This is very bad.
Given that most Java classes are written along with their accessors, equals comparing attributes are said to be a bad idea.
However, I would probably first check to see if the ID field is not null. If it is null, I would fall back to attribute comparison. If it is not null, then just use it and not do anything else. Does this make sense?

Given Person class with attributes name, surname. When Person at the age of 21 changes its name is it still the same Person (equals gives true)?
If you write equals basis on attributes, then, it would not be the same person, so in my opinion the best approach is to test equality of entities basis on their business identifier (unique and immutable over the whole entity lifecycle).

Another solution could be to use an UUID field in your entity.
In this case, you could use the UUID as primary key or just for equals.
#Entity
public class YourEntity{
#Id
private String uuid = UUID.randomUUID().toString();
// getter only...
}

Related

DDD - Value Object flavor of an Entity

I've seen some DDD projects with value object representations of entities.
They usually appear like EmployeeDetail, EmployeeDescriptor, EmployeeRecord, etc. Sometimes it holds the entity ID, sometimes not.
Is that a pattern? If yes, does it have a name?
What are the use cases?
Are they value objects, parameter objects, or anything else?
Are they referenced in the domain model (as property) or are they "floating" just as parameters and returns of methods?
Going beyond...
I wonder if I can define any aggregate as an ID + BODY (detail, descriptor, etc) + METHODS (behavior).
public class Employee {
private EmployeeID id;
private EmployeeDetail detail; //the "body"
}
Could I design my aggregates like this to avoid code duplication when using this kind of object?
The immediate advantage of doing this is to avoid those methods with too many parameters in the aggregate factory method.
public class Employee {
...
public static Employee from(EmployeeID id, EmployeeDetail detail){...};
}
instead of
public class Employee {
...
public static Employee from(EmployeeID id, + 10 Value Objects here){...};
}
What do you think?
What you're proposing is the idiomatic (via case classes) approach to modeling an aggregate in Scala: you have an ID essentially pointing to a mutable container of an immutable object graph representing the state (and likely some static functions for defining the state transitions). You are moving away from the more traditional OOP conceptions of domain-driven design to the more FP conceptions (come to the dark side... ;) ).
If doing this, you'll typically want to partition the state so that operations on the aggregate will [as] rarely [as possible] change multiple branches of the state, which enables reuse of as much of the previous object graph as possible.
Could I design my aggregates like this to avoid code duplication when using this kind of object?
What you are proposing is representing the entire entity except its id as a 'bulky' value object. A concept or object's place in your domain (finding that involves defining your bounded contexts and their ubiquitous languages) dictates whether it is treated as a value object or an entity, not coding convenience.
However, if you go with your scheme as a general principle, you risk tangling unrelated data into a single value object. That leads to many conceptual and technical difficulties. Take updating an entity for example. Entities are designed to evolve in their lifecycle in response to operations performed on it. Each operation updates only the relevant properties of an entity. With your solution, for any operations, you have to construct a new value object (as value objects are defined to be immutable) as replacement, potentially copying many irrelevant data.
The examples you are citing are most likely entities with only one value object attribute.
OK - great question...
DDD Question Answered
The difference between an entity object and a value object comes down to perspective - and needs for the given situation.
Let's take a simple example...
A airplane flight to your favourite destination has...
Seats 1A, 10B, 21C available for you too book (entities)
3 of 22 Seats available (value object).
The first reflects individually identifiable seat entities that could be filled.
The second reflects that there are 3 seats available (value object).
With value object you are not concerned with which individual entities (seats) are available - just the total number.
It's not difficult to understand that it depends on who's asking and how much it matters.
Some flights you book a seat and others you book a (any) seat on a plane.
General
Ask yourself a question! Do I care about the individual element or the totality?
NB. An entity (plane) can consider seats, identity and / or value object - depending on use case. Also worth noting, it has multiple depends - Cockpit seats are more likely to be entity seats; and passenger seats value objects.
I'm pretty sure I want the pilot seat to have a qualified pilot; and qualified co-pilot; but I don't really care that much where the passengers seats. Well except I want to make sure the emergency exit seats are suitable passengers to help exit the plane in an emergency.
No simple answer, but a complex set of a pieces to thing about, and to consider for each situation and domain complexity.
Hope that explains some bits, happy to answer follow-up questions...

Do we need to generate equals and hashcode in sub class everytime even super class generated and serialized in java?

I have a class called User.java and the code is as follows,
public abstract class User implements Serializable {
// serialVersionUID
private Integer userId;
private String userName;
private String fullName;
// Constructor()
// Getters and Setters
// equals()
// hashCode()
}
And I have Contact.java class,
public class Contact extends User {
// serialVersionUID
private String phoneNumber;
private String address;
// Constructor()
// Getters and Setters
}
So my question is even User class generated equals and hashcode methods do I need to override it again in the sub class Contact?
And also I am using lombok and the IDE is IntelliJ. I see that when I am generating equals and hashcode through IDE there are to select the template for example,
Default
Apache commons lang 3 like that.
When generating I see that generated hashcode is different for example,
lombok contains different code
Apache commons lang 3 contains different code
So what is the difference between each of those, difference between each generated hascode()?
What can I try to solve this?
Normally, yes, but first you need to think about what equality even means in the context of a User object. For example, I bet you'd consider any User where the ID is equal, to be equal, and there is no need or point to check for equality in the userName or fullName fields, or the phoneNumber field. Possibly you want to check only userName, or only the combination of userId and userName. It's not about the code you want to write, it is about what you consider the definining equality relationship between any two given user objects.
The answer is complicated.
There is no easy answer to this question. Therefore, let's first talk about why you'd even want to add such methods.
What is equals/hashCode for
The point of these two methods is to give you the ability to use instances of your User class (or your Contact class) as keys in a java.util.Map of some sort, or to put them in some java.util.List and have these types actually fulfill what their documentation tells you. If you add objects of a type without equals/hashCode impls to, say, an ArrayList and then call .contains() on this, it won't do what you expected it to. If you try to use them as keys in a map, it won't work right.
Thus, if you aren't planning on putting User objects in lists or maps, then there is no need to fret about any of this stuff. Don't write the methods at all. Move on with life.
Okay, but I do want to do that.
That gets us to..
Then think about what your type actually represents
What does an instance of the Contact class actually represent?
It represents a row in a database (could even be a textfile or a non-SQL based engine); changes to the object will result in changes to the underlying DB, for example.
It represents a contact in a user's address book. Not 'address book' as in 'the data store that the contact app I am writing is using', but 'the actual address book'.
Depending on your answer, the equals/hashCode will be wildly different.
It represents a row in the DB
For SQL-based DB engines, the DB engine has a clear and universally understood definition for equality. If you say that an instance of Contact represents a row in your DB, then it is logical that the equality definition in your java code must match that of SQL, and that definition is simply this: Equal Primary Key? Then they are equal.
PKs can be anything and can be multiple columns, but the vast majority of DB designs use an auto-generated single numeric column for primary key, and given that you have a 'userID' as a field, this sounds like your design.
That means the definition of equality you desire is: equality means: Same userID. But it gets worse: For e.g. hibernate you can make an instance of User and have that object exist in java memory without you ever saving it to the DB yet. That means (for auto-generated primary keys), that the object effectively doesn't have a primary key and for 2 objects without a primary key, even if they are utterly identical in all ways, that thus means they are not equal - and that is such a crazy definition of equality (equal if the userID fields are equal unless the userID fields represent the placeholder value indicating 'not saved to db yet', then not equal, even if they are identical in every way), that no auto-generated tool implements this, you'd have to write it yourself.
It represents an entry in the address book
Then the definition is effectively flipped: that a contact entry has a id is an implementation detail of the database and is the only field in the entire class that is not an actual intrinsic part of the contact as a concept, thus equality is probably best defined as: "Identical, except for the DB id, that does not matter as it is not an intrinsic property of a contact".
Again you need to take some extra actions here; lombok, intellij, eclipse -- all these tools cannot know any of this, and will by default just assume you intend that 2 instances are equal only if every field is equal.
Um.. how do I choose?
Well, go back to what equals/hashCode is for: To make instances of this stuff function as keys in maps and for contains and such to give proper answers when these instances are stored in java lists. So, what do you want to occur if you store 2 separate instances of Contact into a list, where somehow they both have the same ID, but a different username value? Depending on your answer, you know which of the two interpretations are correct.
Why are these tools generating different impls of hashCode?
They don't. Not really. The point of hashCode is very simple:
If any two given objects have different hashcodes, they cannot possibly be equal.
That's it. That's all it means. Two objects with equal hashcodes don't need to be equal (you'd have to invoke a.equals(b) to find out), but two objects with non-equal hashcodes are not equal, and there is no need to invoke a.equals(b) to find out. This is not enforced by java at all, but you're supposed to write it that way (ensure that if 2 objects have non-equal hashcode, that they cannot be equal). If you fail to do so, instances of your classes will do bizarre things when used as e.g. keys in hashmaps.
There are many ways to write an algorithm that leads to this effect. This explains why there are small differences. But, they are all about equally effective (they generate different hashcodes for known different objects about as efficiently, and the hashCode method runs about equally performant, for all of these different tools).
Subtyping
Subtyping is extremely complicated in regards to equality. That's due to the rules as documented in Object's equals and hashCode javadoc. This answer is very long already so I won't get into why, so you'll just have to do some web searching or take my word for it. However, asking tools to auto-gen equality/hashCode impls in the face of a type hierarchy is very tricky.
It sure sounds like you want to lock down what equality (and therefore hashcode) means at the class User level (namely: equality is defined by having the same userID. Perhaps the same username if that sounds more applicable to your situation. But no more than that), in which case you should write these methods yourself, and they should be:
public final boolean equals(Object other) {
if (other == this) return true;
if (this.userId == null) return false;
if (!(other instanceof User) return false;
return this.userId.equals(((User) other).userId);
}
public final int hashCode() {
return userId == null ? System.identityHashCode() : 61 * userId.intValue();
}
Why?
These define equality by way of 'both have a userID, and they are equal'.
They are consistent with the rules (such as: any 2 equal objects will neccessarily have equal hashcodes).
They are simple.
They are 'final', because otherwise this gets incredibly complicated, and you can't allow subtypes to redefine equality on you, that can't work, due to the rule that a.equals(b) must match b.equals(a).
Why 61? It's just an arbitrarily chosen prime number. Pretty much any number would do; an arbitrary prime is very very very slightly more efficient in exotic cases.
Actually I want the other definition
Then use lombok (disclaimer: I am a core contributor there, so this is me rating myself), because it has the best equals implementation, and you won't have to look at the code or maintain it. Mark your userId field with the #EqualsAndHashCode.Exclude annotation, and mark the Contact class with #EqualsAndHashCode(callSuper = true), and User with #EqualsAndHashCode (or something that includes that, like #Value) - the callSuper is needed to tell lombok that the parent class has a lombok-compatible equals implementation.

Best approach for linking diverse entity types in JPA

Short version for the hasty:
There's various tables/entities in my domain model which have the same field (a UUID). There is a table where I need to link rows/instances of such entities to other JPA-managed entities. In other words, the instance of the field in that link table won't be known up-front. The two approaches I can think of are:
Use an abstract entity and a TABLE_PER_CLASS strategy, or
use an #MappedSuperClass store the class name of the instance in the link table as well, or something similar that lets me define logic for getting the actual instance from the right table.
Both have advantages and disadvantages in terms of complexity and performance. Which do you believe to be best, is there maybe a third option, or have you tried something like this in the past and would advice/strongly warn against?
Long version in case you want more background:
I have a database/object model wherein many types have a common field: a universally unique identifier (UUID). The reason for this is that instances of these types can be subject to changes. The changes follow the command model and their data can be encapsulated and itself persisted. Let's call such a change a "mutation". It must be possible to find out which mutations exist in the database for any given entity, and vice-versa, on which entity a stored mutation operates.
Take the following entities with UUIDs as an (extremely simplified) example:
To store the "mutations", we use a table/entity called MutationHolder. To link a mutation to its target entity, there's a MutationEntityLink. The only reason this data isn't directly on the MutationHolder is because there can be direct or indirect links, but that's of little importance here so I left it out:
The question comes down to how I can model the entity field in MutationEntityLink. There are two approaches I can think of.
The first is to make an abstract #Entity annotated class with the UUID field. Customer, Contract and Address would extend it. So it is a TABLE_PER_CLASS strategy. I assume that I could use this as a type for the entity field, although I'm not certain. However, I fear this might have a serious performance penalty since JPA would need to query many tables to find the actual instance.
The second is to simply use #MappedSuperClass and just store the UUID for an entity in the entity field of MutationEntityLink. In order to get the actual entity with that UUID, I'd have to solve it programmatically. Adding an additional column with the class name of the entity, or something else that allows me to identify it or paste it in a JPQL query would do. This requires more work but seems more efficient. I'm not averse to coding some utility classes or doing some reflection/custom annotation work if needed.
My question is which of these approaches seems best? Alternatively, you might have a better suggestion, or notice I'm missing something; for example, maybe there's a way to add a type column even with TABLE_PER_CLASS inheritance to point JPA to the right table? Perhaps you've tried something like this and want to warn me about numerous issues that would arise.
Some additional info:
We create the database schema, so we can add whatever we want.
A single table inheritance strategy isn't an option. The tables must remain distinct. For the same reason, joined inheritance doesn't seem a good fit either.
The JPA provider is Hibernate and using things that are not part of the JPA standard isn't an issue.
If the entities don't have anything in common besides having a uuid I'd use the second approach you describe: use MappedSuperclass. Making the common superclass an entity would prevent you to use a different inheritance strategy if needed, would require a table for that super entity even if no instances exist and from a business point of view it's just wrong.
The link itself could be implemented in multiple ways, e.g. you could subclass MutationEntityLink for each entity to map (e.g. CustomerMutationEntityLink etc.) or do as you described it, i.e. only store the uuid as well as some discriminator/type information and resolve programatically (we're using that approach for something similar btw.).
You need to use #MappedSuperclass while inheriting associations/methods/properties whereas TABLE_PER_CLASS is generally used when you have entity and sub-entities. If there are entities having an association with the base class in the model, then use TABLE_PER_CLASS since the base class behaves like an entity. Otherwise, since the base class would include properties/attributes and methods which are general to such entities not related to each other, using #MappedSuperclass would be a better idea
Example1: You need to set alarms for some different activities like "take medicine", "call mom", "go to doctor" etc. The content of the alarm message does not matter, you will need a reminder. So use TABLE_PER_CLASS since alarm message, which is your base class is like an entity here.
Example2: Assume the base class AbstractDomainObject enables you to create login ID, loginName, creation/modification date for each object where no entity has an association with the base class, you will need to specify the association for the sake of clearing later, like "Company","University" etc. In this situation, using #MappedSuperclass would be better.

hashCode() method for related entities

I read that when using JPA you should implement hashCode()/equals() for your entities.
So Eclipse for example has this nice feature to generate those methods for the classes.
But what fields do i have to choose?
I read that choosing the Long id; field of your entity is not a good idea. (right?, why?)
One should use a business key (some fields of the entity which can be used to identify the entity. right?) in the hashCode()/equals() methods.
Considering following scenario:
1:n relation between A and B...
is it a good idea to use those references in the hashcode() method?
if i do so i sometimes run into java.util.ConcurrentModificationException or Stackoverflow exceptions.
What about collections variables? i think i should not use those in my hashcode() function...
can somebody give me hints?
Consider using the fields (as few as possible) that will uniquely identify the object. If it were a Person it might be first, middle and last name. Or better still, Social Security Number if US Person. I don't see any issue with using a DB ID so long as the table cannot contain duplicate entities. In general, the identity of an object should not require checking the identities of it's associated objects (the 1:n relationship) but just the local fields.
Equals and hashcode methods should be always implemented either on primary key or on your business key this is necessary if you want to adhere to requirements of your persistent manager. Check here
You can implement your own logic in hashcode to get the unique number.For example
you can do some combination of ^-ing
(XOR-ing) a class's instance variables (in other words, twiddling their bits), along
with perhaps multiplying them by a prime number.

DDD: Entity and its identifier

I have an entity in my system, which naturally needs an identifier so that it can be uniquely identified. Assuming the database is used for generating the identifier with Hibernate, using the native strategy, then obviously the application code is free of this responsibility of assigning identifiers.
Now, can an instance of that entity be considered valid before it is persisted and gets its identifier?
Or should I use some other strategy to assign my entities their identifiers so that it gets its identifier when its constructor is called?
That's an extensive topic, but here are two possibilities:
define your hashCode() and equals(..) contracts based on business keys. For example, for a User entity, this would be the username, rather than the auto-generated id. Thus you will be able to use the entity in collections before it is persisted
use UUID as a primary key, and handle the generation yourself. See this article by Jeff Atwood and this article demonstrating a way to use it with Hibernate
(Since you mention DDD and hibernate, take a look at this article of mine)

Categories