If you are brave enough to get out of the confort zone and structure of applications over symfony and follow a more clean path you will may be facing some challenges on the road, like integration with ORMs (Doctrine).
In this particular post i will talk about about some strategies i have follow in the past and what i have learn from it.
Business Model and Doctrine Entities/Documents
The first strategy i follow was to keep the doctrine mapping under the bundle Entity or Document directory and inherit from business clases. Given that i want to leave the business package without any reference to database or framework i choose to use yaml or xml for the mapping language instead of annotations.
The first challenge with this strategy is that objects are created on the business model so when it gets to the entity/document manager it doctrine does not recognize it and throw and error. The way i found to handle this was to implement a fromBusinessEntity function on each entity/document class so before it get persisted or updated it go through this function and convert it self to an object under the doctrine scope.
This has a big downside, since you have to convert every object and those objects may have references, embedded documents or any other complex structure it will require a big logic to handle it, and with more code comes performance degradation.
The only good side of this approach is that developers that are use to use symfony as it is and do not have interacted with a model designed by package responsibilities may feel a bit confortable on where to find the entities/documents.
Business Model as Doctrine Entities/Documents
But i cant stop with that solution i feel it was not right so i decide to dig in to the doctrine mapping configuration. My findings were that we can actually tell doctrine were to seek for mapping references so we can do something like
# Doctrine Configuration doctrine_mongodb: connections: default: server: "%mongodbServer%" default_database: "%mongodbDatabase%" document_managers: default: mappings: BusinessPackage: type: yml dir: "%kernel.root_dir%/../../BusinessPackage" prefix: BusinessPackage
This way your business classes can act as doctrine entities/documents reducing complexity on your framework business integration and dropping the performance degradation that may be introduced on previous approach.
Between previous approaches i personally choose the second one because i like to keep my code as clean as possible and business independently of frameworks.
It may be even a better way to this and im counting on it, so we can keep learning and improving.
Every time we decide to use a new approach on how to deal with frameworks, architecture patterns, code structure, etc; we put our self in front of a new challenge, we may have the experience from old projects we may try new approaches, the goal must be always learn from our mistakes and improve the next phase.