0

I have recently come across the idea of persistence ignorance, the idea that your domain model should be ignorant of the persistence layer of the application, and that got me thinking.

I have been doing my best to keep different parts of the application loosely coupled, wrapping things like the ORM in interfaces so that I could (relatively) easily swap them out if needed. However, I did find aspects of the ORM and, even more so, the underlying database leaking through into my domain model, forcing me to restructure my data model to fit into and within the limits of the database.

So I was thinking of adding a persistence data model that would be specifically for dealing with the ORM and would directly map to database tables and relationships. Then, when reading data, map from that data model to the domain model, and when writing data, map from the domain model back to the persistence data model. (Currently working in .NET so I can use the wonderful AutoMapper for converting from one type to the other).

Is something like this common practice? Is it worth the extra maintenance overhead when making changes to the domain model? Could this be considered an anti-pattern?

4
  • It is common pattern. The reason why Automapper was invented Commented Oct 27, 2017 at 20:32
  • Are you a self taught programmer ? Pretty much any decent school class where ORM is taught will taught you that too.So yes it is a common practice, is it worth ? it depends off your project. It is not an anti pattern, but if you implements this badly it can end with very poor performance and Oout of memory error by loading the whole base in memory. Commented Oct 27, 2017 at 21:03
  • I am self taught. Commented Oct 27, 2017 at 23:54
  • 1
    @Entith curious to know about being “self-taught”. You’ve had no formal instruction in programming at all? Keep in mind that you would not likely learn about ORMs at the university level in computer science. I’ve found the only people who will dismiss you for being “self-taught” are people who need to feel that the gobs of money that they spent on education is worth more than experience. It’s a prejudice based on their own self-importance. Commented Oct 28, 2017 at 0:45

2 Answers 2

3

I think perhaps part of what you are struggling with here is that ORMs are designed to sit in the same spot in the design where the persistence layer would decouple the storage and the domain model. If you want to use an ORM and do this, the only effective solution is to push the ORM down and treat it as the underlying storage which is precisely what you've correctly concluded.

However, I did find aspects of the ORM and, even more so, the underlying database leaking through into my domain model, ...

This is one of my biggest issues with heavyweight ORM. It's very 'opinionated' and tends to be roughly isomorphic to the structure of the underlying database. At the same time, it's easy (even encouraged) to hook it directly into your domain model which then becomes roughly isomorphic to the database structure. You can fight this with complex configurations in many ORM tools but I think (from experience) that it's a bad idea as you will likely create a ton of issues getting the ORM to behave as needed.

So where you end up is essentially an extra layer with a lot of types that exist simply to interface between your domain layer and your ORM. This is where the 'extra' maintenance comes in.

An alternate solution is to ditch the ORM and build a persistence layer that maps directly from the domain layer to one or more persistence layers. In the kind of work my team does, we typically start with multiple storage systems/targets that we need to support and expect to have to swap or accommodate a change in those targets on the scale of every 1 to 2 years. So this kind of decoupling is pretty essential for us to be able to also accommodate functional requirement changes in the domain and yes, it can be done.

7
  • "An alternate solution is to ditch the ORM and build a persistence layer that maps directly from the domain layer to one or more persistence layers." This sounds interesting, can you elaborate on this a bit more, or link to some resources on this approach? Commented Oct 28, 2017 at 2:29
  • I'd love to but I'm not sure where to start. The technique is simply to create domain classes and then define a persistence layer that creates these objects and persists them to the database. What you use to do this is up to you. You can do it with ORM and essentially you are on that path. One thing that came to mind is that you might want to be sure you are not building an Anemic Domain Model. The rest of this stuff won't matter much if you don't get the domain model right. Commented Oct 30, 2017 at 13:37
  • I am still poking around to find something to help with your question. It's a pretty large topic. A lot of the design depends on what kind of application this is. Is it a basic CRUD app or something more esoteric? Commented Oct 30, 2017 at 14:44
  • Here are few links to start. I'm a little hesitant to point you to this one, mainly because the author has a very 'I know the truth' attitude. He will engage with you if you reply to his posts. I wouldn't recommend it. Here's some more Fowler. He's pretty solid and even-handed on this subject. Here's a post about micro-ORMs. I'm not a C# guy so I can't vouch for any specific tools. Commented Oct 30, 2017 at 16:17
  • Thanks for the info! That first article is interesting; I can see where he is coming from, and to some extent I agree, but it seems like you'd have a lot of duplicated boilerplate-ish code littered in all your domain classes, and if you ever need to change your persistence layer, you have to reimplement every domain class. I actually read Fowler's article on Anemic Domain Models not too long ago and am still trying to wrap my head around it. All my data models so far have been anemic, with data access handled by the ORM and domain logic handled in services and hooks into read/write events Commented Oct 30, 2017 at 19:37
-1

In my view it’s not worth the effort. In the late 90s I worked for a non-profit and they had a dbase IV based application— I don’t even remember what the app code was written in. Pascal? COBOL? I don’t remember. Anyway it got rewritten for the next technology, MS Access and VB.

Every project I’ve been involved with hasn’t ever needed to rip out the ORM layer nor the database. These just aren’t the parts of the system that need a lot of change. Business logic, front-end— that’s where all the changes tend to be.

I don’t really understand some people’s obsession with swapping out infrastructure. It’s almost never worth it. When you do start to be restricted by your infrastructure, it will likely be only in a tiny part of your application for a few specific use-cases, and in that scenario you’re better off moving those small, core parts to infrastructure made specifically for your use case, and that infrastructure will be so radically different that you’ll need to rewrite your data model entirely anyway.

10
  • "and that infrastructure will be so radically different that you’ll need to rewrite your data model entirely anyway." If you need to rewrite your data model because you changed your infrastructure, that pretty much proves they weren't actually decoupled. Commented Oct 27, 2017 at 21:06
  • 1
    @JimmyJames the point is that the mapping stops making any sense at all. It becomes a category error. Like moving from a relational schema to an HBase data store. Trying to “map” it is a waste of time and won’t help you get the benefit of the new store. Commented Oct 27, 2017 at 21:08
  • 3
    You seem to be suggesting that it's not possible to decouple the storage and the domain model. If you want to argue that, that's fair enough but I think you should be direct about it. I've personally done it, seen it done, and I know lot's of people who claim to have done it. Commented Oct 27, 2017 at 21:12
  • @JimmyJames no I’m saying that it’s not worth the extra work. Yes it’s possible but in the end any purported benefit is lost. And a good ORM will already take care of abstracting away the underlying proprietary store. So it should make it easy to go from MS SQL Server to Oracle or PostGres. That’s what the ORM is for. But spending time to go from an SQL server to some other kind of store, like NoSQL of some kind, will probably be a change in bounded context and the domain / data model will be radically different. You get no benefit from adding another layer of abstraction there. Commented Oct 27, 2017 at 21:15
  • 1
    I would say that most ORMs make this difficult. This is part of why I don't like heavyweight ORM. if you dispense with the ORM, it gets a lot easier. I think we can debate the value. It's very expensive to rewrite an application simply to move to a new persistence mechanism. Needing to do so is a failure in design, IMO. Commented Oct 27, 2017 at 21:19

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.