I am wondering if it is possible to create a relationship between two entities that reside in separate databases.
For example if we took the solution found here http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html and created a one to many relationship with Users in the customer database to Posts in the default database.
Is this something that is supported by Symfony2 and Doctrine?
Using different object managers (entity managers) doesn't allow the object graphs to intersect. That case is too complex and isn't managed by Doctrine ORM.
If you need such a case, keep the object graphs disconnected by saving the identifiers of the related objects (old style) instead of a reference to them, then manually get the objects through services. You can find a fairly good example of how this would work in an example of connection between Doctrine2 ORM and Doctrine2 MongoDB ODM. Alternatively, you could also use a #PostLoad event listener that populates data in your entities by creating the link through the repositories I've linked in the example. Same for #PostPersist (which should instead extract the identifiers for the related objects), but beware that this technique can become really messy.
Also, if your RDBMS supports cross-database operations on a single host, you can just use a single EntityManager and reference the other table with #ORM\Table(name="schemaname.tablename").
Related
I've recently started developing in .NET core.
When developing I encountered the situation that I have to make very similair models that aren't quite the same. For example, let's talk about a booking model:
Frontend: Here I need a model that gets posted as a JSON to my backend and gets deserliazed to a sort of FrontendBooking model.
Backend: I need to add Customer data to the booking, therefore I need to add fields like: CustomerName and CustomerAddress, based on their CustomerId. The backend needs to provide this data, I do not want the frontend to determine these fields. I combine these models to prepare it for an API call. To a model called RequestBooking.
API: I sent RequestBooking to an API and get a response with a similair object that has for example a Status and BookingId added, this was added to the model by the API. So I need to deserialize this to an object called: ResponseBooking.
Database: Finally I wish to store the object to a database, not all properties of the model are relevant however, therefore I create another model called: DatabaseBooking and store this to the databse.
When a property is added, removed or changed. Then I'll have to change it for each of these models.
Is there a design pattern or some other solution, so this is more manageable?
Also, what is best practise for naming these models? Naming them all Booking doesn't feel quite right and adding what they're used for doesn't feel quite right either.
Thanks in advance.
Well, in general you will need different (although similar) models at least at these levels:
Server: here you can make use of Domain Driven Design. You will have an object Booking that is responsible for its logic and contain all properties and methods like e.g. MarkAsCancelled. You can use Entity Framework to use the same object in the database, which will correspond to a database table. EF allows you to mark some properties as not being saved in the DB. Also you can set up EF in the DbContext class and thus not use DB specific attributes in the class. So one object for DB and backend business logic.
API: obviously you cannot send your domain object to the API, e.g. REST. In the API you may want to combine properties of several domain objects or hide some properties. You will have to define a set of Data Transfer Objects (DTOs), e.g. BookingDto. How to convert your domain objects to DTOs? Solutions like AutoMapper may help. You just set up convertion rules once.
Now you can describe your API in e.g. Swagger. With Swagger Codegen you can than generate code for your server (.net) and client (e.g. JS).
In the end you will have to support the following:
API definition (e.g. Swagger). Code for server DTOs and client
objects is autogenerated. You modify API definition once, both sides
get new objects.
DDD Models that also are used for the Database. They
may be faily independent from your DTOs. Mapping is handled for you
semi-automatically by e.g. Automapper
All said is just a suggestion. All the layers and number of objects can and should be adapted to the specific needs of your project. E.g. you may want to use separate objects for the database if you are not using a relational mapper like EF or do not want to mix DB and logic.
I manage complex entities, with multiple and different relationships with other entities, which themselves are linked to multiple other entities sometime.
I am making an edit form, and would like to avoid having to code manually different Doctrine 2 queries to udpate every entity linked to the modified entity.
Is it possible to cascade merge entities in Doctrine 2 ? By that, I mean modifying an entity and its linked entities (oneToMany, ManyToMany... relationships) and then applying the changes to the entity and the linked entities in cascade.
If not, what is the 'clean' way to apply modifications to all the concerned entities ? Does it need to be manually done, by calling merge or update on every entity ?
It seems you are working on Symfony (correct me if I'm wrong).
On symfony forms, when you are working with underlying objects, you sometimes need to put 'by_reference' option to 'false' in order to correctly handle the underlying modified objects.
See that : https://symfony.com/doc/current/reference/forms/types/form.html#by-reference
Hope it helps.
Most probably the problem has nothing to do with symfony but more with your doctrine relationships. You should check your associations as changes made only to the inverse side of an association are ignored by doctrine. Refer to the documentation.
I am currently looking into the repository patterns and read that repository patterns can be implement in 2 way:-
One repository per entity (non-generic) : This type of implementation
involves the use of one repository class for each entity. For example,
if you have two entities Order and Customer, each entity will have its
own repository.
and
Generic repository : A generic repository is the one that can be used
for all the entities, in other words it can be either used for Order
or Customer or any other entity.
Then I read about the Unit of Work concept and how it can relieve us from database inconsistencies that can be cause by the first way.
My confusion is regarding the second way.
Why would I be needing to use 'Unit of work' when I have created a generic repository?
Since there is no way for any inconsistency to occur.
One way to minimize redundant code is to use a generic repository, and
one way to ensure that all repositories use the same database context
(and thus coordinate all updates) is to use a unit of work class.
But since I am going to have a single generic repository then what is the need?
Usualy You don't have "single" generic repository.
In complex applications, sometimes you have to use many instances in a controller
(for example
var productsRepo = new Repository<Products>();
var userRepo = new Repository<Users>();
This are two different instances of generic repository, and they can cause inconsistent in db (or even Exceptions, if both have different dbContext and you try to modify entities in both repositories).
Thats why You have to manage dbContext properly, and Unit Of Work is one of many ways to accomplish it.
I'm actually having 3 entities: Bounty, Document, and Comment. When i first made the Comment entity, it was to serve the document Commentary purpose. Later i have added a newer entity called "Bounty", and i was expecting to use the same Comment entity that i was already using in the Document entity.
I wish to avoid having one DocumentComment entity, and another BountyComment entity.
Is having one Comment Entity is a good way to procede, or should i rather separate them in two different entities ?
If grouping entites is a good practice, how can i make them fit when there can be duplicate entry ?
If both identities have the exact same structure and this fact is never going to change, you could group them together. However, every comment belongs to some other entity, so if it belongs to a Document, it needs a property "document". If it belongs to a Bounty, it needs a property "bounty". So the two are not the same.
If you are using ORM (e.g Doctrine), you can use a shared base class and extend from it. Doctrine will create seperate tables for each type, but you can share functionality between the entity classes. See http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html
Is it possible to change relationships between tables in EF6 without losing data? From my research, my understanding is that many-to-many relationships can be configured using the Fluent API in the onModelCreating method.
What wasn't clear was whether I would be able to change a table from a one-to-many relationship to a many-to-many relationship with a junction table.
There isn't an explicit migration operation to move the data around like that, what you do is:
Alter your model as desired, either through the fluent API, POCO objects or designer.
In the Up method of the generated migration class, use the DbMigration.Sql method to move the data around in beween the generated Create/Add and Drop statements. Yes, this does involve manually writing the required SQL statements.