Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

repository pattern vs ORM

What good is a repository pattern when you have an ORM?

Example. Suppose i have the following (fictional) tables:

Table: users

pk_user_id
fk_userrole_id
username

Table: userroles

fk_userrole_id
role

Now with an orm i could simply put this in a model file:

$user = ORM::load('users', $id);

Now $user is already my object, which could easily be lazy loaded:

(would be even nicer if things are automatically singular/pluralized)

foreach ( $user->userroles()->role as $role )
{
    echo $role;
}

Now with the Repository pattern i'd had to create a repository for the Users and one for the Roles. The repository also needs all kinds of functions to retrieve data for me and to store it. Plus it needs to work with Entity models. So i have to create all of those too.

To me that looks like alot of stuff do... When i could simply get the data like i described above with an ORM. And i could store it just as easy:

ORM::store($user);

In this case it would not only store the user object to the database, but also any changes i made to the 'Roles' object aswell. So no need for any extra work like you need with the repository pattern...


So my question basically is, why would i want to use a repository pattern with an ORM? I've seen tutorials where to use that pattern (like with Doctrine). But it really just doesn't make any sense to me... Anyone any explanation for its use in combination with an ORM..??

like image 749
w00 Avatar asked Apr 14 '12 17:04

w00


People also ask

Is orm a repository pattern?

The ORM is an implementation detail of the Repository. The ORM just makes it easy to access the db tables in an OOP friendly way.

What is repository pattern?

The Repository pattern. Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.

Should I use repository pattern with CQRS?

If you're applying CQRS and Vertical Slice Architecture you'll likely want a repository to build up Aggregates. However, for a Query, you may want to just get the data you need rather than an entire aggregate (or collection of aggregates) to build a view model.

Is repository pattern still valid?

Developers used to write SQL statements in their code and the repository pattern was a way to move that SQL out of individual methods scattered throughout the code base. Developers building applications with ASP.Net Core and Entity Framework Core should not use UoW and Repository pattern anymore.


2 Answers

The ORM is an implementation detail of the Repository. The ORM just makes it easy to access the db tables in an OOP friendly way. That's it.

The repository abstract persistence access, whatever storage it is. That is its purpose. The fact that you're using a db or xml files or an ORM doesn't matter. The Repository allows the rest of the application to ignore persistence details. This way, you can easily test the app via mocking or stubbing and you can change storages if it's needed. Today you might use MySql, tomorrow you'll want to use NoSql or Cloud Storage. Do that with an ORM!

Repositories deal with Domain/Business objects (from the app point of view), an ORM handles db objects. A business objects IS NOT a db object, first has behaviour, the second is a glorified DTO, it only holds data.

Edit You might say that both repository and ORM abstract access to data, however the devil is in the details. The repository abstract the access to all storage concerns, while the ORM abstract access to a specific RDBMS

In a nutshell, Repository and ORM's have DIFFERENT purposes and as I've said above, the ORM is always an implementation detail of the repo.

You can also check this post about more details about the repository pattern.

like image 169
MikeSW Avatar answered Oct 06 '22 00:10

MikeSW


ORM and repository pattern...depends on setup.

  1. If you use your ORM entities as the domain layer, then please use no repositories.
  2. If you have a separate domain model and you need to map from that model to ORM entities and so perform a save, then repositories are what you need.

More details you find here (but must be logged to linked-in). Also to understand the difference, check out the definition of the repository pattern.

Most people use classes that they call repositories, but aren't repositories at all, just query classes - this is how/where you should place your queries if you decided to go with the #1 option (see answer above). In this case make sure not to expose DbContext or ISession from that query class, nor to expose CUD-methods from there - remember, Query class!

The #2 option is a tough one. If you do a real repository, all the inputs and outputs on the repository interface will contain clear domain classes (and no database related object). It's forbidden to expose ORM mapped classes or ORM architecture related objects from there. There will be a Save method also. These repositories might also contain queries, but unlike query classes, these repos will do more - they will take your domain aggregate (collection and tree of entities) and save them to DB by mapping those classes to ORM classes and perform a save on ORM. This style (#2) does not needs to use ORM, the repository pattern was primarly made for ADO.NET (any kind of data access).

Anyhow these 2 options are the 2 extremes we can do. A lot of people use repositories with ORM, but they just add an extra layer of code without real function, the only real function there is the query class like behaviour.

Also I'd be careful when someone talks about UnitOfWork, especially with ORM. Almost every sample on the internet is a fail in terms of architecture. If you need UoW, why not use TransactionScope (just make sure you got a wrapper which uses other than Serializable transaction by default). In 99,9% you won't need to manage 2 sets of independent changes in data (so 2 sets of OuW), so TransactionScope will be a fine choce in .NET - for PHP i'd look for some open-session-view implementations...

like image 27
baHI Avatar answered Oct 05 '22 22:10

baHI