Videogame Developer

lunes, 23 de abril de 2012

Discussion about best practices managing entity relations in a database agnostic way


Hello, I'm playing a bit figuring out what's the best way to decouple database relations among persisting entities to make it database-agnostic and more service-oriented, in a way that the entities relates each other through an abstraction service layer.

So I think that all the database relations between entities that belongs to different services must be avoid, then these relations have to be defined in a way that not implies to know how the other object is stored.

let's put a simple example, I have a couple of Bundles, UserBundle and BlogBundle:
UserBundle has an object called User which is persisted in MySQL database and  all accesses to save/find the object are encapsulated by the UserManager.
BlogBundle has the blog object which is persisted in MongoDB, all accesses to save/find the object are encapsulated by the BlogManager.

I have the next two main concerns about how to make the relation:
1) What to store in the User Entity ?
2) How to retrieve the Blog object from User Entity ?

1) What to store in the User Entity?
If I want to relate a user to a blog then I must persist something in the User table that links the user to the blog, but what kind of thing ? I can use the _id from MongoDB Blog Document but it is a database autogenerated field, also I can use a centraliced service to generate a custom objectId, Imo at least every persisting object must implement a getObjectId method to have an uniform way to get its id not matter how they are stored and what kind of id field uses as primary key (if used).

In the Blog entity class I'd have its oid:
//Class MQM/BlogBundle/Document/Blog
/**
 * @ORM\Column(name="oid", type="string", length=255, nullable=true)
 */
private $oid;
//...

public getObjectId()
{
return $oid;
}

The User entity class would have its own oid and the blog_oid:
//Class MQM/UserBundle/Entity/User
/**
 * @ORM\Column(name="oid", type="string", length=255, nullable=true)
 */
private $oid;

/**
 * @ORM\Column(name="blog_oid", type="string", length=255, nullable=true)
 */
private $blog;
//...

public getObjectId()
{
return $oid;
}

2) How to retrieve the Blog object from User Entity ?
The second part of this is whether or not to retrieve/hydrate the Blog(convert Blog objectId string into a Blog object like Doctrine would do).

//Example in UserManager class:
public function findUserByUsername($username)
{
$user = $this->repository->findOneBy(array('username' => $username));
$user->blog = $this->blogManager->findBlogBy(array('oid' => $user->blog));

return $user;
}

Maybe it requires more database accesses but keeps all blog retrieval/hydration centraliced in the User class keeping things DRY, otherwise everytime everywhere when it's needed to get the Blog object from the user it would be needed to call the BlogManager->findBlogBy(...) method.

1 comentario: