I have a method which allow me to edit an Entity in the database. This method takes an Entity as an argument. This Entity is an edited version of the existing one in the database. I would like to get the database version of the Entity to compare the value and perform certain taks. But it seems that
> I have a method which allow me to edit an Entity in the database. This > method takes an Entity as an argument. This Entity is an edited version of > the existing one in the database. > I would like to get the database version of the Entity to compare the > value and perform certain taks. But it seems that
> gives me the modified object as well, and the databse has not been updated > yet.
> Is there a way to get the unmodified object ? > Thanks for your help :)
> -- > You received this message because you are subscribed to the Google Groups > "doctrine-user" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/doctrine-user/-/b560uzv1wcsJ. > To post to this group, send email to doctrine-user@googlegroups.com. > To unsubscribe from this group, send email to > doctrine-user+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/doctrine-user?hl=en.
Hey, thanks for your answer. $em->getUnitOfWork()->getEntityChangeset($entity); Looks nice, but it returns an empty array. Do I have to call another method before using this ?
> Hey, thanks for your answer. > $em->getUnitOfWork()->**getEntityChangeset($entity); > Looks nice, but it returns an empty array. Do I have to call another > method before using this ?
> To post to this group, send email to doctrine-user@googlegroups.com. > To unsubscribe from this group, send email to > doctrine-user+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/doctrine-user?hl=en.
> Hey, thanks for your answer. > $em->getUnitOfWork()->getEntityChangeset($entity); > Looks nice, but it returns an empty array. Do I have to call another > method before using this ?
Hi,
I had a similar problem. I wanted an equivalent of the Doctrine 1.x $entity->isModified(), and after much documentation and API searching, UnitOfWork seemed to provide the answers.
I am not an expert on the innards of Doctrine, so bear in mind that this might be semi-wrong, but my conclusions were that:
$uow->getEntityChangeset($entity) or in my case $uow->isEntityScheduled($entity) would provide no answers until:
$uow->computeChangeSets(); or $uow->computeChangeSet($class, $entity); was called.
However, when I then went and later called $em->flush(), the UoW would then internally call these methods again, and the entity would be queued *twice*, which then led to nasty errors from the database (e.g. primary key constraint error due to Doctrine attempting a double INSERT of the same object).
My conclusions were that UoW was not meant to be messed with, that I should be interacting with Doctrine at a higher level, and that if I wanted to know these things, I'd have to track them myself, externally to Doctrine. This seemed silly since it's a duplication of work (Doctrine's doing it, as am I), but it seemed like the only viable route :/
Of course, if anyone knows of a solution, that would be wonderful, but I believe this is the cause of your empty array.
I'm using SonataAdminBundle. When I edit an object, I have to perform some actions (file moving maily) before the object is saved to the database. So I use the preUpdate($entity)<http://sonata-project.org/bundles/admin/master/doc/reference/saving_h...> method. So the object is already persisted in the database as I'm editing it. $entity is the modified object.
@Mark, I'm only want to UPDATE objects, so maybe using $uow->computeChangeSets() will work for me. I'll give a try and let you know what happen.
Using $uow->computeChangeSets(); seem to work for me, but I need to access other property of the object as well. So $em->refresh($entity); must be the best way. I juste need to work on the correct implementation of the __clone() method, as $em->copy() isn't implemented yet :(
> Using $uow->computeChangeSets(); seem to work for me, but I need to > access other property of the object as well. > So $em->refresh($entity); must be the best way. I juste need to work on > the correct implementation of the __clone() method, as $em->copy() isn't > implemented yet :(
> To post to this group, send email to doctrine-user@googlegroups.com. > To unsubscribe from this group, send email to > doctrine-user+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/doctrine-user?hl=en.
> To post to this group, send email to doctrine-user@googlegroups.com. > To unsubscribe from this group, send email to > doctrine-user+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/doctrine-user?hl=en.
In case someone want to do the same thing, here is my solution :
1. In your entity, implement the __clone() method (remember to clone your object property) ; 2. Where you want to retrieve your original object :
<?php$original = clone $entity; // Create a copy of your object$this->getDoctrine()->detach($entity); // Prevent your object from being refreshed$original = $this->getDoctrine()->merge($original); // Attach the copy to the EntityManager$this->getDoctrine()->refresh($original); // Get the database version of the entity // Do stuff $this->getDoctrine()->detach($original); // Detach the copy from the EntityManager$original = $this->getDoctrine()->merge($entity); // Attach the entity back to the EntityManager
Maybe not the best way, but it works :) As Marco said, you need to unset the id field.
Actually, it's not working. When I detech and merge back the entity, Doctrine update AND insert the object in the database. So the code I gave in my last message update $entity and insert a copy in the database. In this the normal behaviour ?
I don't really understand why you detach and merge the same object to the entityManager... Yes, it is the default behavior to refresh it, but still, you got a problem there. The logic imho (taking your code and rewriting it) is following:
$em->detach($entity); //first detach. We don't want to track anything! $copy = clone $entity; //we don't want to clone relations to managed entities, thus the clone happens after detaching $copy->setId(null); //we unset the identifier, otherwise the entitymanager will not insert the new object
//work with your object
$em->persist($copy); //it's about persisting, not merging. $em->merge($entity); //if you really need the entity $em->flush();
> Actually, it's not working. > When I detech and merge back the entity, Doctrine update AND insert the > object in the database. So the code I gave in my last message update > $entity and insert a copy in the database. In this the normal behaviour ?
> To post to this group, send email to doctrine-user@googlegroups.com. > To unsubscribe from this group, send email to > doctrine-user+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/doctrine-user?hl=en.
Doctrine is really new for me, so I might be trying to do stuff the wrong way. To get the original object, I found $uow->getOriginalEntityData($entity). It looks fine right now. No need to clone the object I get as a parameter, no detach or merge.
> Doctrine is really new for me, so I might be trying to do stuff the wrong > way. > To get the original object, I found $uow->getOriginalEntityData($entity). > It looks fine right now. No need to clone the object I get as a parameter, > no detach or merge.
> To post to this group, send email to doctrine-user@googlegroups.com. > To unsubscribe from this group, send email to > doctrine-user+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/doctrine-user?hl=en.
I'm managing Products, and each Product belongs to a Category. So when someone edit a Product, I want to check if the Category has change. If it's the case, I need to update the Product position in the new Category, and also update the Poducts position in the old Category (ie. decrementing other product position so there is no hole). That's why getting the changeset didn't fit my needs, as the Product position wouldn't be in the array returned by the unit of work. I also need to move folders if the product name/category is changed.
So $uow->getOriginalEntityData($entity) is really is best thing to do all this Thanks for your help Marco :D
> I'm managing Products, and each Product belongs to a Category. So when
> someone edit a Product, I want to check if the Category has change. If it's
> the case, I need to update the Product position in the new Category, and
> also update the Poducts position in the old Category (ie. decrementing
> other product position so there is no hole).
> That's why getting the changeset didn't fit my needs, as the Product
> position wouldn't be in the array returned by the unit of work.
> I also need to move folders if the product name/category is changed.
> So $uow->getOriginalEntityData($entity) is really is best thing to do all
> this
> Thanks for your help Marco :D
It returns this: array('field_name' => array($old, $new), …);
Calling getOriginalEntityData returned null and computeChangeSets also needed because changes were not computed.