ORM: Data Mapper vs Active Record

Which one is better and why?

  • Active Record: The record (entity) itself can actively change the DB
  • Data Mapper: There is an external object that persists the entities

Active Record

As I previously mentioned, the entity itself can be created, updated or deleted. In PHP for example, Eloquent is an Active Record ORM developed by the Laravel community.

final class UserCreator
{
public function create(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$address->save() # Address is stored in the database

$user = User::createFrom($userInfo->user());
$user->address = $address; // Set relationship
$user->save(); # User is stored in the database
}
}

Data Mapper

In the data mapper, we need an external class that will update the DB. In PHP for example, Doctrine is the de facto Data Mapper ORM for Symfony.

final class UserCreator
{
public function __construct(
private EntityManager $entityManager,
) {}

public function create(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$user = User::createFrom($userInfo->user());
$user->address = $address; # Set relationship

# We persist all objects we want to update
$this->entityManager->persist($address);
$this->entityManager->persist($user);

# Finally, flushing the entity manager will execute the SQLs
$this->entityManager->flush();
}
}

Repository Pattern

The repository pattern is a design pattern that hides the database logic into a new class, exposing only the methods we want to provide to the user.

# App/User/Domain
interface UserRepository
{
public function save(UserInformation $userInfo): void;
}

~~~~

# App/User/Infrastructure
final class ActiveRecordUserRepository implements UserRepository
{
public function save(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$address->save()

$user = User::createFrom($userInfo->user());
$user->address = $address;
$user->save();
}
}

final class DataMapperUserRepository implements UserRepository
{
public function __construct(
private EntityManager $entityManager,
) {}

public function create(UserInformation $userInfo): void
{
$address = Address::createFrom($userInfo->address());
$user = User::createFrom($userInfo->user());
$user->address = $address;

$this->entityManager->persist($address);
$this->entityManager->persist($user);
$this->entityManager->flush();
}
}
final class UserCreator
{
public function __construct(
private UserRepository $userRepository,
) {}

public function create(UserInformation $userInfo): void
{
$this->userRepository->save($userInfo);
}
}

--

--

Competitive, entrepreneur and autodidact. Hard worker, lover of technology and free software.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jesus Valera Reales

Competitive, entrepreneur and autodidact. Hard worker, lover of technology and free software.