views:

335

answers:

4

Having a parent object Employee with a list of Address child objects:

class Employee
{
    List<Address> addresses;
}

and a Repository method:

void Insert(Employee);

Should the code within this repository attempt to save the parent Employee as well as the child Address objects, or should separate repositories handle the parent and children objects?

If separate repositories, then when saving the Employee object and its children within the client code, should this be separate calls at that level, combined in some sort of service or is there another alternative?

+3  A: 

The repository should handle the entire aggregate object (parent and all children), because that's what makes it a repository. If you're saving root and child objects separately, then the pattern you're using isn't really called a repository (although it might still be a perfectly good solution)

"Repository" is just a convenient name for a particular data access pattern that loads and saves entire aggregates in one go - so when you say to another developer that you're using the repository pattern, they know that that's what's going on.

Dylan Beattie
Absolutely, though there is obviously an exception for when you have many Employees with the same Address.
ilya n.
A: 

I would try and go with a Unit of Work pattern where you open, make changes, commit, and then it just figures out the right thing to do.

If you're in a relational database, you'll end up with something like Hibernate having a mapper per table. If you are in a non-relational database, you might have to get creative, and mark domain objects as IAggregateRoot or something, to know which ones have their own repositories and which don't.

For example, if Employees are stored in one SOA, and Addresses in another, they'd each be IAggregateRoots, and ideally the Unit of Work would automatically hand each of the dirty instances off to its corresponding repository for saving.

So then its transparent to client code, but not a useless layer of indirection (like services mostly are, in the java world anyway--not always, but the ones I've seen).

I love DDD, but I think it over-hypes repositories, and, empirically, causes a lot of confusion because people are always asking how to do them correctly.

Unless I had a system with known multiple SOA-based backends (and not just "hey, we might be Amazon someday and need that"), I would shy away from repositories, personally. Hibernate-based mappers/DAOs/something, sure, but they seem simpler and more concrete than repositories.

A: 

I prefer a repository per table but glue them together into an aggregate repository:

public RootEmployeeRepository (
  IEmployeeRepository employeeRepository, 
  IAddressRepository addressRepository)
{
  // init
}

public SaveEmployee (Employee employee)
{
  // call IEmployeeRepository to save the employee record minus childen
  // call IAddressRepository to save employee.addresses
  // commit all changes to the DB via UnitOfWork
}
Todd Smith
A: 

I prefer NHibernate which handles cascading saves for you.

ShaneC