-
-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POPOs data is not being persisted #21
Comments
I have resolved this issue with DoctrineEventSubscriber <?php
use Doctrine\Common\Inflector\Inflector;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Common\EventSubscriber;
class JsonDocumentSubscriber implements EventSubscriber
{
/**
* @return array
*/
public function getSubscribedEvents(): array
{
return [
Events::preUpdate
];
}
/**
* @param PreUpdateEventArgs $event
*/
public function preUpdate(PreUpdateEventArgs $event): void
{
$subject = $event->getObject();
$em = $event->getEntityManager();
$uow = $em->getUnitOfWork();
$meta = $em->getClassMetadata(get_class($subject));
$jsonObjects = $this->filterJsonObjects($meta);
if($this->forceUpdateJsonDocument($jsonObjects, $subject)) {
$uow->recomputeSingleEntityChangeSet($meta, $subject);
}
}
/**
* @param ClassMetadata $meta
*
* @return array
*/
private function filterJsonObjects(ClassMetadata $meta): array
{
$jsonObjects = [];
$fieldMappings = $meta->fieldMappings;
if(is_array($fieldMappings)) {
foreach($fieldMappings as $filed => $options) {
if($options['type'] === 'json_document') {
$jsonObjects[] = $filed;
}
}
}
return $jsonObjects;
}
/**
* @param array $fields
* @param $object
*
* @return bool
*/
private function forceUpdateJsonDocument(array $fields, $object): bool
{
$hasUpdates = false;
if(!empty($fields)) {
foreach($fields as $fieldName) {
$methodGet = 'get'.Inflector::camelize($fieldName);
$methodSet = 'set'.Inflector::camelize($fieldName);
$newValue = null;
$actualValue = $object->{$methodGet}();
if(is_array($actualValue)) {
$newValue = [];
foreach ($actualValue as $k => $v) {
$newValue[$k] = clone $v;
}
}
if(is_object($actualValue)) {
$newValue = clone $actualValue;
}
if(null !== $newValue) {
$object->{$methodSet}($newValue);
$hasUpdates = true;
}
}
}
return $hasUpdates;
}
} |
@Dragonqos How are your entities mapped? I can't get this to work - preUpdate event isn't fired. Or maybe you have other fields which are changed too? |
@thatside-zaraffa Yes, I am updating "updated_at" field manually when needed, to fire event. |
@Dragonqos Seems it is the reason of your subscriber working :) |
Actually I've come to same solution - added updatedAt field and update it manually. Not the greatest way to work... |
The problem is with the way UOW compares objects - it is simple "equals" comparison
My code is slightly different (simple object instead of array as |
Would you be able to open a PR with a failing test? |
So regarding to what @thatside-zaraffa said, there's no work for this bundle? Or is there any listener that could get all POPOs and clone them if changed? |
Any news about this issue ? |
Maybe I can give some background here. So the issue is that Doctrine does not blindly execute So if your object stays the same (PHP compares the object reference when you do Does this help? |
Thank you @Toflar , I knew that Doctrine checked the status of the changes before saving but I did not think the object appear as the same even if a nested object was changed :). |
Is there a way to make the embedded objects behave like associations so that doctrine checks them too (instead of just the parent object) with something like an implicit cascade="persist" ? |
Imho there's not. |
Thanks for your nice bundle. I got the issue: if I change the json_document related plain php object property, it won't persisted by default.
The text was updated successfully, but these errors were encountered: