Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping between the persistence model and the domain model

I have done an IMMENSE amount of reading about domain driven design and have done some fairly complex projects with that design. All of them had their flaws and anti-patterns that were realized along the way. Understandable as this was a learning process. I, however, am stuck on a major concept that I cannot seem to resolve via Google (maybe I'm just not coming up with the right search terms) or by my own trial and error.

I have read several articles that claim emphatically to keep your Domain Model and your Persistence Model separate. Don't let things like an ID leak into your Domain Model unless there is a domain purpose for that ID. With that policy, how does one persist a Domain Model IN PRACTICE? All the articles I have read talk about this in the abstract, but I cannot find a concrete example that DOESN'T violate this.

I have a relatively large and complex web application that I'm building and would like to achieve the "best" Domain and Persistence separation I can. I am using a hand-rolled ORM (yes, yes, I know - I shouldn't - blah blah blah - however, the underlying tables and queries are much too complex to use something like EF or NHibernate well). In this accounting package at a large university, I have General Ledger Journal Entries with the following structure:

 Public Class Journal

    Public Property AccountCode As SFSAccountCode = Nothing

    Public Property Amount As Decimal = 0

    Public Property BudgetCategory As BudgetCategory = Nothing

    Public Property [Date] As DateTime = Nothing

    Public Property ChildAccount As ChildAccount = Nothing

    Public Property Description As String = ""

    Public Property FiscalYear As SFSFiscalYear = Nothing

    Public Property Fund As Fund = Nothing

    Public Property JournalID As Int32 = -1

    Public Property Notes As String = ""

    Public Property Program As String = ""

    Public Property Source As JournalSource = Nothing

    Public Property Status As JournalEntryStatus = JournalEntryStatus.Open

    Public Property TransactionType As TransactionType = Nothing
End Class

Without including the uniqueID (JournalID), how can I map an instance in the Domain Model to an instance in the Persistence Model? From my understanding, you are to consider an object unique by its invariants. Easy, if your object is only one or two properties as strings or ints. I clearly have many properties of which several are domain models themselves.

I'm sure there is some key concept that I have just missed - can anyone point me to a resource (with concrete code as bonus!) to help explain how one can map between a persistent model with database IDs to a domain model without?

By the way, yes I know my properties should be private sets for good domain design. And they will be once I can figure out the mappings between persistence and domain better. And I happen to code in VB.NET but can read Java or C# fine, as I'm sure most examples will be in one of those two languages.

like image 488
Eric Dieckman Avatar asked Aug 23 '14 12:08

Eric Dieckman


People also ask

What is persistence domain model?

A domain model should always be concerned with domain BEHAVIOR, while a persistence model, at most, it stores domain object STATE. The persistence models what you want to store from an object and that data will be used to restore the object.

What is a persistence model?

A persistence model assumes that the future value of a time series is calculated under the assumption that nothing changes between the current time and the forecast time.

What is a domain model in programming?

In software engineering, a domain model is a conceptual model of the domain that incorporates both behavior and data. In ontology engineering, a domain model is a formal representation of a knowledge domain with concepts, roles, datatypes, individuals, and rules, typically grounded in a description logic.

What is domain model DDD?

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. The Domain Model itself could be a diagram, code examples or even written documentation of the problem.


1 Answers

According to Domain Driven Design:

Some words about entities and values

There are entitiy objects (entities) and value objects (values). Values are identified by a set of values (or fields). Thus, if we have two value objects with same fields, they are not disinguishable for us (as model in real life). Often value objects are immutable.

Entity objects are not identified by contained values. Entity objects are identified by its own unique existance. We cannot say that two persons with same name presents single real man.

For example:

class ProductAmountPair {
    public Product Product { get; set; }
    public int Amount { get; set; }
}

class Order {
    public int Id;
    public IList<ProductAmount> { get; set; }
}

ProductAmount is a value, and Order is an entity (actually it depends on concrete case).

To identify entity object, it is necessary to determine some unique value (key). In some domains keys are given externally (from real life), but another ones requires to generate it and thus application itself defines a way to do that.

So, conclusion is: for entities we have to introduce key field to identify them. It is necessary since entities cannot be identified by a set of values they contain.

Databases

Ok, what about database and its role.

Today databases are not just only data storage, but are complicated mechanism for ensuring of the data integrity, transactins processing, etc. Very often complex tasks like concurrent access are solved by applications just by "broadcasting" them to database.

By the same reasons databases are often used to generate key values, they propose good reliable mechanism to obtain new unique values. So, keys are generated by database because it is easy to implement, and keys are used to map domain model entities to persistance model because it is natural.

One can say, that DB engines requires to create primary keys for each table, and thus every class in domain should have key field, and thus it is entity. But:

  • Relational DB engines uses primary key for referencing and it should not affect domain model in any way
  • For real value types (like depicted ProductAmount class) you should not use stored in DB key to obtain corresponding object from database. It has no sense because value objects cannot be identified by some key (by definition of value type). But key stored in database is used to load object associations. So this operation must be encapsulated by ORM. Moreover the only way to get value object from database is to obtain it from field of some entity.

Persistance and domain

Why should we consider databases (even relational databases!) when talking about domains? In his DDD book Eric Evans says "do not confront with technologies and paradigms".

Sometimes, because of strong performance or realiablity requirements we have to give up some DDD purity and clearness and make domain model more (for example) "relational" (I mean class-table mappings mostly).

We just have to deal with it.

For same reasons we can admit a partially "techincal" role of key field of entity. But also we admit its main role as domain identification attribute.

like image 96
Valentin P. Avatar answered Dec 05 '22 13:12

Valentin P.