Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Domain Driven Design - Domain model vs Hibernate Entity

Are Hibernate Entity is same as the domain models?

See the following example.

Method 1 - Domain model and Entity are same class. Domain model "is-an" entity

@Entity
@Table(name = "agent")
class Agent
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "agent_number", unique = true, nullable = false)
    private String agentNumber;

    @Column(name = "agent_name", nullable = false)
    private String agentName;

    // Busines logic methods
}

Method 2 - Domain and Entity are different functions. Domain model "has-an" entity

class Agent
{
    // Hibernate entity for this domain model
    private AgentEntity agentEntity;

    // Getters and setters to set the agentEntity attributes

    // Business logic
}

From the above 2 methods, which of them are the correct way to implement DDD? I believe method 2 is the right way because you are essentially controlling the access to a sensitive object and the enclosing object (Domain model) has all the business logic/operations on the domain model. But my workplace colleagues suggests that they are essentially the same. And according to them the purpose of Hibernate Entity is to represent the domain model in a given system. Modelling the entity as the domain model actually makes the design simpler. This is because the repository takes an Entity to execute CRUD operations. So if model "has-an" entity, then the repository must be dependency injected into the domain model to save the entity. This will make the design unnecessarily complicated.

like image 330
Vino Avatar asked Apr 19 '19 03:04

Vino


People also ask

Is domain model same as entity?

In practical purpose, domain and model are the same, while entity is also a domain/object that would be used to store in the database. Some people are tried to re-explain such topics but none of them are canon.

What is the domain model in Domain-Driven Design?

The Domain Model is your organised and structured knowledge of the problem. The Domain Model should represent the vocabulary and key concepts of the problem domain and it should identify the relationships among all of the entities within the scope of the domain.

What is domain model in hibernate?

A relatively new feature in Hibernate allows you to create a domain model in Java that is fully dynamic, such as a model without any concrete classes but only HashMaps. Hibernate also supports a domain model representation with XML documents. Let's start with the example application.

What is an entity in the domain model?

Entities represent domain objects and are primarily defined by their identity, continuity, and persistence over time, and not only by the attributes that comprise them.


1 Answers

Since you have mentioned a technology in this case Hibernate, that means that you are talking about an implementation. Domain Driven Design is about both the abstract e.g. the Model and it's Implementation.

Models can be implemented in different ways. In your example you have shown two different implementations that represent the same Model.

This article talks about the problem that you are facing.

You asked if the Domain Model is the same as a Hibernate Entity. The answer is NO.

Hibernate Entity is a technology specific thing, in this case it's an object that is part of an ORM framework. Hibernate Entity and DDD Entity as defined by DDD are different things as the DDD Entity is an abstract thing, if defines an idea (a pattern) and gives guidelines of what this idea is and what it represents. Hibernate Entity is a Java object that is instantiated, tracked, persisted, discarded and garbage collected.

People just use the same term for different things and this can lead to confusion (can't blame them, naming things is one of the two hard problems in software).

You use Hibernaty Entities or any other type of technology specific thing like Entity Framework Entity (that is the same thing, an object in a OO program) to implement a Domain Model. The same Domain Model can be implemented in different languages using different technologies. These implementations will vary based on what the technology provides.

For example if you are writing a NodeJs backend with a MongoDB and you want to use an ORM to implement a Domain Model you will be stuck with using an Active Record pattern (probably Mongoose) because these are the only ones that people have implemented (at least I couldn't find any other frameworks that are not Active Record, if you find any please let me know). Implementing DDD in such a way can be very tricky (and can really suck).

In the DDD book Eric Evans talks about how technology can help you implement a Model or can fight you all the way. When it fights you or doesn't provider good mechanisms you just how to work around that.

Sometimes ORMs have requirements and you don't want to expose these things to your other code, so you can use a Wrapper like in your Method 2. Some of them include things like public get set method, public constructors etc. Most of them use reflection and can have private stuff but still there are many issues like having a private constructor without parameter to satisfy the framework and your code get's messy with a lot of stuff that are not related to your model but are there because your framework needs them (YUCK!). This can lead to bugs too. It's easier to make a mistake by having default constructor instead of having nice constructors with parameters or static factory methods. This wrapper can represent a more purer domain model without having the necessary evil that frameworks carry so you can use them.

In one project this got so ugly that we decided to go with raw SQL in Repositories so we don't have to deal with all the stuff of the framework. The implementation was nice, pure and we did it faster. Some people think that a framework speeds things up and it's true most of the time, but when the framework fights you and the code is buggy, debugging is not fun, so writing a raw SQL can be a breeze. In this case Following the guidelines of DDD by using aggregates our model was nicely decoupled and we didn't have complex queries that can make the development slower.

like image 78
expandable Avatar answered Oct 29 '22 13:10

expandable