2

I need a data mapping/repository solution and would like to avoid having to write my own.

Doctrine seems to fulfill all the requirements apart from one, but I just don't know how to do it.

I am working with a legacy database and I would like to have my domain objects completely unrelated to the database until we are able to phase out the old application part by part (which will take at least a year). That means I need a way to add fields from other tables to an entity.

Here is an example:

<?php
namespace Entities;

class Article
{
    protected $id;
    protected $name; // from article table
    protected $description; // from article_info table, joined from article table
    protected $stock; // from article_variation_info, joined from article_info table

    ...
}

The doctrine docs seem to indicate two possible solutions:

  • Creating entities for all the tables and then using custom getters/setters to add a field to an entity
  • Use native SQL to get the entity data and for each repository query (see here)

I would like to avoid the first option because I want to create a clean domain model for the new application free from old limitations/bad decisions from the past. Having to create entities for each table seems to be counterproductive here.

The second options seems a little better, but if I have to write all the SQL I might as well code my own PDO repositories and mappers instead.

Am I missing something or is doctrine just not the ideal solution for what I am trying to do?

Patrick
  • 922
  • 11
  • 22
  • 1
    Consider using SQL views. – Cerad Feb 05 '14 at 10:41
  • @Cerad I did consider that, but inserting etc doesn't seem to work. At least not on MSSQL, – Patrick Feb 05 '14 at 10:47
  • Can you write (insert/update) to real tables, and just use views for class model reads? Or, if you want to try writing to views, it [should be possible on SQL Server](http://stackoverflow.com/a/3127568/472495), depending on how you construct your view. – halfer Feb 05 '14 at 11:11

1 Answers1

2

Doctrine 2 is not ideal for your problem. It really wants the one table per entity relation. On the other hand, once you transition then things would be good.

I do think views are your best solution. I know capability is limited but you should be able to work through it.

However, your first option is viable. What is important is that you have a nice clean interface for your new models. Your application is only aware of the model interfaces. The model layer would have no persistence code in it all.

NewModel
    NewArticleModel implements NewArticleModelInterface
    NewArticleModelInterface
    NewArticleRepositoryInterface
NewEntity
    NewArticleEntity extends NewArticleModel
    NewArticleEntityRepository implements NewArticleRepositoryInterface
OldEntity
    OldArticleDoctrineEntity
    OldArticleDoctrineRepository

The trick is to have the NewArticleEntityRepository be responsible for building the NewArticleEntity out of the OldArticleDoctrineEntity's.

Eventually, when the database has been updated to support the NewArticleEntity directly, you just need to adjust the repository or maybe plug a new one in. Again, your application only knows about the model level interfaces.

In fact, regardless of what approach you take, creating a persistence neutral model layer is probably the way to start.

Cerad
  • 48,157
  • 8
  • 90
  • 92