I am try to remove the associations on a entity ticket on run time just to reduce the size of the return array, I am new at Symfony I have been working previously on Cakephp there in Controller we use this
$this->User->unbindModel(array('hasAndBelongsToMany' => array('Friend')), true);
Is there any equalivant of unbindModel Available in Symfony
Related
I have a problem during testing a symfony App with phpunit.
I created a service and it works well but when I execute the service in my tests doctrine throw me an exception
A new entity was found through the relationship 'PointOfSale#country' that was not configured to cascade persist operations for entity
In my service I do this:
$pointOfSale->setCountry($this->getCountry($name));
private function getCountry(string $name): Country
{
$country = $this->entityManager->getRepository(Country::class)->findOneBy(['alpha3Code' => $name]);
return $country;
}
I don't understand why this entity is not managed by UnitOfWorks. Indeed when I do the following code I have an exception only during test
$country = $this->entityManager->getRepository(Country::class)->findOneBy(['alpha3Code' => $name]);
$this->entityManager->refresh($country);
[ERROR] Entity Namespace\Country#000000001bfea0ed00000000602457d6 is not managed. An entity is
managed if its fetched from the database or registered as new through EntityManager#persist
How can I fix this ?
Solution was discuss here:
https://github.com/doctrine/DoctrineBundle/issues/1112#event-3005473120
[doctrine changelog note] (https://github.com/doctrine/DoctrineBundle/blob/1.12.x/UPGRADE-1.12.md#unitofwork-cleared-between-each-request)
While troubleshooting the same problem with PhpUnit Testing producing "A new entity was found through the relationship" errors I realized I was actually getting different Entity Manager instances thanks to this question. What I did was move the self::bootKernel() from my __construct function to a new "startUp" function that I run at beginning of each test function and then I started getting the correct Entity Manager each time instead of a different one each test.
I may be missing something, but now my tests pass and produce the same results as my actual program.
I'm refactoring the code in one of my Controller to put it in a service.
In the Controller the entity manager is targeting a db connection called legacy.
The problem is, I did not injected the Entity Manager in my service but just the OrderRepository.
How can I target the good db connection with the repository in my service without the Entity Manager?
OrderController
// In my Controller
$em = $this->getDoctrine()->getManager('legacy');
$em->persist($order);
$em->flush();
OrderService
// In my Service
public function __construct(OrderRepository $orderRepository)
{
$this->orderRepository = $orderRepository;
}
public function updateOrderStatus(Order $order)
{
// some code ...
$this->orderRepository->save($order);
}
Based on some comments it would appear that the basic issue is having multiple entity managers. Nowadays there is a great deal of automated functionality which works well for one entity manager but no so much for multiple managers.
You basically need to define your services manually.
# services.yaml
# assume we have
# doctrine.orm.default_entity_manager and
# doctrine.orm.legacy_entity_manager
# already defined through configuration
# define legacy repository
order_repository.legacy:
class: Whatever\Repository\OrderRepository
factory: ['doctrine.orm.legacy_entity_manager', 'getRepository']
arguments:
- 'Whatever\Entity\Order'
# define default repository
order_repository.default:
class: Whatever\Repository\OrderRepository
factory: ['doctrine.orm.default_entity_manager', 'getRepository']
arguments:
- 'Whatever\Entity\Order'
# then your service
Whatever\Service\MyService:
'#order_repository.legacy'
And you should be good to go. Note that your repository needs to extend EntityRepository and not the doctrine bundle's ServiceEntityRepository.
And if you feel this is too much work then just inject the doctrine bundle's entity manager registry and do what the ControllerTrait::getDoctrine($name) does.
You must forgot that you can always get the entity manager inside your repository just like this:
$em = $this->getEntityManager();
then you can use it normally calling persist, flush etc.
Note that the Repository class itself is agnostic to functionalities of the database access layer like insert or update so it should call entity manager to execute them.
I'm using Codeception to test a Symfony 3.4 project with Doctrine2 module enabled.
The problem is that I can't access related entities on an entity I receive by calling grabEntityFromRepository() function. So if I do:
$person = $I->grabEntityFromRepository('AppBundle:Person', ['id' => 1]);
$address = $person->getAddress(); // Address is a one to one related entity to person
The $address variable is NULL.
Is this an expected behaviour or can it be tweaked in the configuration somewhere?
I have read the documentation many times at http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html but I still don't get it.
What's the purpose of persiting entities?
I have the following code
$em = $this->getDoctrine()->getManager();
$user = $this->container->get('security.context')->getToken()->getUser();
if ($user) {
$user->enabled(1);
$em->flush();
}
It works very well.
Why should I add the
$em->persist($user);
before the flush ?
persisting an entity just means that the entity manager can manage the entity. otherwise it doesn't know about it.
EDIT: if you are working with an entity that has been pulled from the entity manager to begin with (in your case, $user), then persisting is not required because the entity manager already "knows" about it. So persisting is only required when creating a NEW instance.
An entity can be made persistent by passing it to the EntityManager#persist($entity) method. By applying the persist operation on some entity, that entity becomes MANAGED, which means that its persistence is from now on managed by an EntityManager. As a result the persistent state of such an entity will subsequently be properly synchronized with the database when EntityManager#flush() is invoked.
http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#persisting-entities
How can I get an entity manager from inside a controller with latest Symfony and Doctrine?
The way described in "The Book" flagged as deprecated now. What is a modern (proper) way to do this?
public function someAction()
{
// getEntityManager() from Doctrine\Bundle\DoctrineBundle\Registry is deprecated
$entityManager = $this->getDoctrine()->getEntityManager();
...
}
Use $this->getDoctrine()->getManager() instead.
Actually, it's best not to make controllers aware of the persistence layer you're using. That stuff should be moved to the Service Layer to abstract the way the data is persisted.