Hexagonal Architecture: Domain Models that are 100% ignorant of persistence and ORM unaware

John
5 min readMar 30, 2016

--

The intention of this post is to share the data that I have gathered in researching and experimenting in making domain models 100% ignorant of persistence and making them ORM unaware. This will also serve as a personal note where I can refer back if I need to.

If you’re wondering what’s the meaning of Hexagonal architecture and how it works, you can refer to these links:

http://victorsavkin.com/post/42542190528/hexagonal-architecture-for-rails-developers

https://www.youtube.com/watch?v=u6oTg5oRH24

What I mean by ORM unaware is the domain models are not tied to an ORM and when you’re using a repository, the objects being returned are just POPOs (plain old php objects in PHP / plain old python objects in Python).

Regarding Python, I tried a popular data mapper named SQLAlchemy. It’s really a nice tool. The only downside that I see is the objects being returned when you fetch a record in the database is a POPO but it is ORM aware (Objects being returned is an instance of SQLAlchemy). I think its a leaky abstraction but I guess they need to do that so they can support things like lazy loading etc…

Gain the skills you need to be a pro at Python development: http://treehouse.7eer.net/c/245500/245646/3944

In PHP, one popular data mapper is Doctrine 2. At first, I thought that the objects being returned when you fetch a record is a POPO but it is ORM aware. But Matthew said that the objects being returned are POPOs and also ORM unaware. I haven’t tried it though. But if its accurate, then its really a good thing. But I’m wondering how do they support things like lazy loading if the POPOs are really ORM unaware. If you know the answer, kindly share it by leaving a comment.

This is a demo app that demonstrates Hexagonal architecture in PHP.

The domain models are 100% ignorant of persistence and are ORM unaware (if Matthew is right) so the core is framework agnostic. It can be dropped in to any framework and wired up to an implementation. He really did a great job demonstrating how it works.

Core:

Core used in Laravel 5:

If you’re interested in Domain Driven Design and REST, check this post that Matthew wrote: http://mattallan.org/2016/rest-and-ddd/

If you have some additional information that you want to share that is related to this post, kindly share it by leaving a comment.

Here is our conversation earlier:

Regarding ddd and hexagonal architecture, is it possible to make domain models 100% ignorant of the persistence layer and make them ORM unaware? http://stackoverflow.com/questions/36273407/is-it-possible-to-make-domain-models-100-ignorant-of-the-persistence-layer-and

Is it possible to make domain models 100% ignorant of the persistence layer and make them ORM unaware?
I’ve been reading and experimenting a lot about domain driven design and hexagonal architecture but I’m still not able to make domain models 100% ignorant of the persistence layer and make then ORM

matthew-james [3:53 PM]
It’s possible. Re: doctrine — defining the metadata mapping doesn’t make the entity aware of the ORM, it makes your ORM aware of the entity.

[3:53]
> the result is an object that is orm aware.
The entity shouldn’t have any knowledge of the ORM, thats what the entity manager is for.

[3:54]
I did a talk on hexagonal architecture and put together a demo app. The app is here https://github.com/yuloh/quicksilver, and the entities dont have any knowledge of the ORM

GitHub
yuloh/quicksilver
quicksilver — A demo bike messenger app, demonstrating BDD and Hexagonal Architecture in PHP

matthew-james [4:00 PM]
> But they don’t have an example on how to persist updates to a model. I guess this won’t be possible without using the technique of ORMs? Like using a metadata etc…

> So I think its not really possible to make domain models 100% ignorant of the persistence layer and make them orm unaware? If it’s possible, how?

You would want to use a repository interface which is bound to an implementation. The implementation uses the ORM, but since it’s behind an interface the domain model doesn’t know or care how it’s persisted.

[4:02]
Hopefully that makes sense. The book implementing domain driven design is pretty good.

— — — Today March 30th, 2016 — — -
johnkevinmbasco [8:14 AM]
@matthew-james thanks ill checj that out. But isn’t the result of queries when using doctrine are doctrine instances? That’s why im saying they are orm aware

johnkevinmbasco [8:35 AM]
@matthew-james: I’m currently checking your laravel 5 quicksilver source code. Where are you defining the metadata mapping for your entities?

[8:39]
ah, saw it now. It’s in `config/mappings.php`. It’s really nice :+1: But the question is, when is the result of `DoctrineDeliveryRepository` when you fetch a delivery? It it a POPO that is not orm aware (not an instance of doctrine) ?

matthew-james [8:39 AM]
yeah it’s a POPO. Doctrine will hydrate it (set all of the values) when it instantiates them

[8:39]
the only weird thing is it uses ‘proxy objects’ for lazy loading collections, which takes a minute to get used to

johnkevinmbasco [8:40 AM]
hmm, if its not an instance of doctrine, how come that the results of doctrine has the ability to lazy load relationships

[8:40]
ah, my question is related to that one.

matthew-james [8:40 AM]
Doctrine uses this https://github.com/doctrine/instantiator to instantiate the class without calling the constructor. Then it sets all the properties using a hydrator

GitHub
doctrine/instantiator
Contribute to instantiator development by creating an account on GitHub.

[8:41]
The proxies are basically this http://ocramius.github.io/ProxyManager/
ProxyManager Documentation
A proxyManager write in php

[8:42]
it’s just setting properties, so it doesn’t need to hijack your class

[8:42]
It does a bunch of dirty tricks like unserializing and then using reflection :grinning:

johnkevinmbasco [8:43 AM]
sounds really neat. very interesting. I’ve tried using a datamapper in python (sqlalchemy) and I noticed that the results are an instance of sqlalchemy, so when you query an entity, it’s orm aware.

[8:44]
anyway, will check those links. thanks a lot!

matthew-james [8:50 AM]
:thumbsup: worth mentioning those mappings are specific to laravel-doctrine, they wrote their own mapping driver that lets you use arrays.

Want to get updated when I publish a new post? Subscribe: http://eepurl.com/bVGMwr

Are you looking for a remote/home based job? Visit http://digitalnomadgigs.com/

You can follow me on Twitter: https://twitter.com/johnkevinmbasco

Looking for a developer? I’m accepting web/mobile development projects. Shoot me an email: basco.johnkevin@gmail.com

--

--