In doctrine documentation I found: "By default, no operations are cascaded." (here http://bit.ly/1frPyLH)
But still one of my database entities is persisting it's associated objects, besides the fact that it has no cascade option in the association.
How can I prevent it from persisting the associated entities ?
It is true and the documentation is still not wrong. =P
Without going deeper on your problem, you need to be aware that by default Doctrine applies a concept called "persistence by reachability". This means that if you are creating a new entity and one of your associations is already managed by UnitOfWork (already known by Doctrine), it will "cascade" the operation.
The problem here is how you read about cascading. In reality, it's not the cascading factor that is updating the associated entity, but it's because it's already managed by Doctrine.
To solve this "problem", you need to modify the way you want Doctrine to deal with your entities by altering the Change Tracking Policy.
I hope this gives you enough information to solve your issue.
Related
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 have an audit mechanism for a project built with ef-core code first approach. I've set the "DeleteBehavior" property to cascade for some tables in "OnModelCreating" function. When I delete an entity, the other one deleted automaticly by cascade delete behavior. That's all good for now and I need to get all deleted entities, but I cannot. The ChangeTracker doesn't contain the cascade deleted entities. How can I get the cascade deleted values? Is there any way to do this?
Cascade Delete happen on the database side. Entity Framework doesn't need to be aware which entity will be deleted.
Entity Framework only tracks changes and delete the base object.
Edit: Answer subquestions
You are right. I'm the owner of EF+.
Technically, a library could handle this, but this will come with a severe performance drawback. I'm not aware of any feature or library which handle the cascade delete scenario for auditing.
Suggestion?
There is some suggestion, but I'm pretty sure you will not like any of them, and I don't either recommend them for performance reason:
Do not use cascade delete (force you also retrieving/deleting related entities)
Create ON DELETE Trigger and Log at database side.
I don't think a good solution exists for this scenario.
I use JSM serialization bundle, which is fine, in symfony 2.
The deal is that I use some User entity, on which I want to define some display var policy. The strategy is somehow the same for all the projet, but the user entity is searched through many different requests, for instance there are some community->users, or or some session->user, or some comment->owner, and if I define some expose strategy, I guess I have to do it for all the including entities, propagating threw all the parents entities.
For instance, if I have got a community entity, where I include community->owner and community->session->user, I want to be able the strategy only at the user level without adding it to session, and community. Now if i dont the serilization display nothing...
Any suggestions folks?
Would it be possible to create a similar entity based on another one? For example, what if I'd like to have user specific tables that are based on one entity. Without any ORM I would just create the same table with a different prefix and do the queries on the table with the specific prefix.
Not sure how to tackle the problem with Symfony 2.5 and Doctrine and I just can't find a concrete example anywhere around, but seems like the solution might be around the Doctrine Event Manager and the Load ClassMetadata event. I just can't make sense out of the documentation.
Without exactly knowing how your schema looks or what you're trying to achieve, it's hard to give a precise answer. But let's try:
If you have two entities which share a common set of properties, but differ in others, you basically do the typical OOP inheritance thing, you create an abstract parent class with the common stuff, and two children with their specific properties.
In Doctrine, there are different inheritance strageties. Read about them at http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html
Each of them has their pros and cons. Basically, you can select if you want everything to be in one or in two tables. Set up a test case and check what works better for you.
Note: The class properties in an abstract superclass (no matter which strategy) must always be private.
I have an entity (eg Image) which is related to many other entities (eg Product or Category). I would like to know which is the best way to prevent the removal of an entity if a relation exists somewhere else (eg I should not be able to delete an Image if it is related to a product). My thoughts are either searching for relations in a repository class and returning results, or doing 'something' at the preRemove lifecycle event of the entity. Which is the best Symfony2 way for preventing removal of related entities?
As long as cascade delete is not set, any directionally entity will prevent delete of the related entity. If your associations are not birectional, you'll have to query form the backside as well.
To expand upon CJ's answer, you may remove delete links, but you will also have to check the entity in controller as well, because any url hacker can delete an object if its id is known.
What I would suggest is you can better of disabled the form delete link when there is a relationship between entities. In that way you can even make the customer understand that there is related entity and he should not remove it before removing the relationship.
You can always check the entity before deleting it and when you actually call certain process in symfony on an entity you actually work on the entire object of that particular entity which gives access to all the values of that entity. So you can check it at that particular point and make conditional statement.
It my personal believe that you should not try to import excess library functions for minor things which can be achieved by you without them. this would make you code easier to understand and even lighter as the prospect for including extra libraries which will most likely have more than what you need