symfony2 / doctrine2 flush createas a select after delete - symfony

I'm removing an entity with these commands:
$this->getEntityManager()->remove($exclusivedeal->getPicture());
$exclusivedeal->setPicture();
$this->getEntityManager()->flush();
$this->getEntityManager()->getConnection()->commit();
The picture Attribute is a ManyToOne relation to the picture entity.
The picture Entity has a function that is called via the postremove Annotation to remove the picture physically from the filesystem. The Flush() operation is doing the sql statements. After the delete Statement, an select statement is called too. This creates the following error:
[2012-06-07 10:06:46] request.CRITICAL: Doctrine\ORM\EntityNotFoundException: Entity was not found. (uncaught exception) at C:\xampp\htdocs\forum\app\cache\dev\doctrine\orm\Proxies\__CG__DankeForumBundleEntityPicture.php line 32 [] []
When i change the annotation to preRemove, everything is fine, but this can't be the solution. I'm doing the same operation on an other Entity with a relation to the Picture Entity.
When i set the cascade remove annotation, the same problem is happened.
Has anyone an idea what i'm doing wrong?
Thank you very much.

I had the same issue and it gave me a lot of headaches trying to solve the problem. I finally found the issue.
The cookbook on the symfony website for handling file uploads with doctrine has been updated to solve this issue.

I just hit this exact same problem and found the issue in my case was because I was using both cascade={"all"} (i.e 'remove') and onDelete="CASCADE".
Changing the cascade to "persist" solved it and Im now able to delete entities with image associations.

Related

Doctrine ORM -Remove attribute from entity?

Very simple thing I want to do, however I fail to find a solution.
I have started to develop my app with Symfony4 bundled with Doctrine. At the beginning I have designed database model but during development I have realized original solution is wrong way for what I want to do. Right now, I want to remove an attribute from entity. In plain SQL I would do ALTER TABLE table DROP COLUMN column then recreate it again with new parameters. However this solution gave me an error in Doctrine, so I have changed PHP model as well. Again, another error. Okay, so this does not look like the way I want to go.
Is there any solution to my problem, except digging too deep in Doctrine? Best would be something simple like described in the SQL command above?
When it comes to doctrine with symfony you should forget about tables, columns etc.. and start thinking with objects (otherwise there's no point in using doctrine for abstraction). For your problem you should simply remove the attribute in your entity.
Then You should use :
php bin/console doctrine:migrations:diff
Which will generate a migration file under the /migrations folder. This file will contain the SQL that doctrine will execute. It allows you to verify if the query is what you expect, if not you can directly modify it in that file or adapt your entity and generate a new migration file.
When you are happy with it, you can execute it with :
php bin/console doctrine:migrations:migrate

[Doctrine2]Flush fail but unitOfWork process correctly

I hope this question haven't already answered but i don't find it.
I using doctrine2 in my symfony (3.4) project. I use persist and flush so many times into it without any problems throught container, in a little piece of code i have some trouble i can't figure out...
In my controller i have a code like this :
$obj = $this->container->get('some.service')->initiateObj(some_params);
$this->getManager()->persist($obj);
$this->getManager()->flush();
// I can't dump here
My object is set and returned correctly from my first code line.
The persist function work perfectly. If i dump my object after persist, doctrine event setting for this object right sets.
After the flush i have an error 500 from my browser (chromium).
I was thinking the problem were in a pre/postFlush event, but when a dump in doctrine EntityManager code, the unitOfWork->commit function work correctly without error and i can dump after it.
But i can't dump in my controller just after flush...
Here the EntityManager from doctrine code :
public function flush($entity = null)
{
$this->errorIfClosed();
$this->unitOfWork->commit($entity);
// I can dump here
}
I haven't any symfony/doctrine log from that, no apache2 log too.
Is anyone have an idea from where an error can throw after the commit function ?
Thank you very much for your help !
I have found my solution last week, in my code.
It was in postPersist event. But i don't really understand why symfony, doctrine... raise any exception, just a blank screen with an error 500.
Thanks you for your help.

Symfony: how to cascade undelete when using SoftDeleteable behavior extension?

My entity User is related to other entities through OneToOne relations, and I'm cascading "delete" for all of them.
I'm using SoftDeleteable behavior extension, so when I remove a User, the entity is not actually removed from the database: the deletedAt field is simply set to DateTime(now), and so are all the deletedAt fields of the related entites.
Now, when I want to restore a User, I do as suggested in the docs:
$em->getFilters()->disable('soft-deleteable');
$user->setDeletedAt(null);
My problem is all the related entities stay deleted when I do this. Any idea how I could cascade the setDeleted(null) to all of them automatically?
Never used this extension but looking at open issues on GH repository I can see quite a few of them related to similar problems when working with associations:
https://github.com/Atlantic18/DoctrineExtensions/issues/656
https://github.com/Atlantic18/DoctrineExtensions/issues/1101
https://github.com/Atlantic18/DoctrineExtensions/issues/505
I'd try first to disable explicitly the filter for each related entity:
$filter = $em->getFilters()->enable('soft-deleteable');
$filter->disableForEntity('Entity\Article');
$filter->disableForEntity('Entity\SomeOtherEntity');
Otherwise I'd add a Listener (and bind it to one of the Doctrine events) to cascade the restore outside of soft-deleteable.

Doctrine2 - A new entity was found through the relationship [...]

Wow, this is very strange:
$bar = new Bar();
$foo = $entity->getFoo();
$bar->setFoo($foo);
$em->persist($bar);
$em->flush();
and I obtain the following message
A new entity was found through the relationship [....]
By reading on the net, I undertand that if fetch two object from two different entity managers, one manager will doesn't know about entities fetched from other manager. Since here I'm into a "db hook" (postPersist) and I've manager injected from DIC, I've tried to change my code in agreement:
$bar = new Bar();
$foo_id = $entity->getFoo()->getId();
$foo = $em->getRepository('MyBundleName:Foo')->findOneBy(array('id'=>$foo_id));
$bar->setFoo($foo);
$em->persist($bar);
$em->flush();
but nothing changed.
Can someone point me to right direction and, most important, explain what's going on here?
UPDATE
I've migrated all code outside db hooks and I've created a new service that will do pretty much same things of hooks but has to called explicitly after flush() Is very strange, however, that nothing changed. I've also tried to use spl_obj_hash onto entity manager for retrieve information about the entity manager who flush object into db and "other one" that will retrieve $foo from db and try to persist $bar.
This is the result:
SPL_OBJ ENTITY MANAGER - 1: 0000000021770e03000000001eda54f7
SPL_OBJ ENTITY MANAGER - 2: 0000000021770e03000000001eda54f7
if I'm not wrong, they're the same entity manager object. I'm pretty confused actually...
UPDATE - WORKING CODE
I've found a "code combination" that will do the work but I'm still pretty confused about it.
If I use first snippet of code (where $foo is retrieved from $entity itself) and flush only $bar, error is still there.
If I use second snippet of code (where $foo is retrieved from entity manager) and persist only $bar, all works properly (obviosuly if I call $flush() without parameters, issue is still there)
I had the same problem and resolved it, I'm posting it because I haven't seen it mentioned anywhere and it might help someone.
I have a service that parses data & persists it to entities, service to which I'm feeding the entityManager & child entities. And I started to have the same error on persist. Using merge() didn't help as it just threw me "A managed dirty+entity [...]" error instead.
After a little digging it seems that as far as Doctrine is concerned the entities I was feeding my service came from a different entityManager, so you actually have to get the entities from the entityManager inside the service if you are using it to persist.
I fixed mine by removing clear
$this->getDoctrine()->getManager()->clear();
I'm not sure since I never had this issue before and right now I'm not in the position to replicate it. But I will give you some options I would try:
If the two entitymanagers are using the same database you can merge (http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html#merging-entities) the entity into the other entitymanager. In this case that will look something like this:
$em->merge($foo);
This makes sure the entity $foo is managed by your entitymanager.
Also, remember that a postPersist is executed after the database operations. I think you have better chances if you try your modified code in a prepersist method.
As the documentation says:
prePersist - The prePersist event occurs for a given entity before the respective
EntityManager persist operation for that entity is executed.
postPersist - The postPersist event occurs for an entity after the entity has
been made persistent. It will be invoked after the database insert
operations. Generated primary key values are available in the
postPersist event.
Full documentation can be found here: http://docs.doctrine-project.org/en/2.0.x/reference/events.html#lifecycle-events
Just try this and let me know the result
Try : $em->merge($bar);
$bar = new Bar();
$foo = $entity->getFoo();
$bar->setFoo($foo);
$em->merge($bar);
$em->flush();
[1] Doctrine - A new entity was found through the relationship
It's not so clear from your code, but I think you create a new $foo, but you don't save it before to save $bar.
Try this:
$em->persist($foo);
$em->flush();
$bar->setFoo($foo);
$em->persist($bar);
$em->flush();
In general you can escape this by using cascade=persist on the association of your entities.

How to access the Doctrine replace() method?

I am doing my first project with Symfony2 + Doctrine, and currently trying to implement replacing records. However when I try to call
$em->save($product);
or
$em->replace($product);
(instead of)
$em->persist($product);
I get fatal errors. So I started digging around to try to find the persist() method so I could see what other methods were available. I searched the entire contents of the vendors/doctrine directory and could not find any references to the persist or flush methods. Where the heck are these located? I tried following the code but quickly got lost.
So the main question: How can I do a replace() with doctrine in Symfony2?
Sub-question: Where are the persist() and flush() methods? Not being able to find them is frustrating in itself.
Incase somebody else is wondering, try looking into:
$em = $service->get('doctrine.orm.entity_manager');
$entity = $em->merge($entity);
$em->flush();
From the docs, Doctrine\ORM\EntityManager::merge():
Merges the state of a detached entity into the persistence context of
this EntityManager and returns the managed copy of the entity. The
entity passed to merge will not become associated/managed with this
EntityManager.
Should do the trick for you.
I don't think that Doctrine's replace() method is supported in Symfony, or at least it is not accessible through EntityManager.
If you need to update your existing entity, then you can simply do it as described here - http://symfony.com/doc/current/book/doctrine.html#updating-an-object.
As for persist() and flush() methods - you can find them in vendor/doctrine/common/lib/Doctrine/Common/Persistence/ObjectManager.php

Resources