Symfony: Create new entity inside doctrine EntityListener with ManyToOne association












2















I'm trying to record every change in quantity of a given item. For that purpose, I listen for a change of an Item entity and wish to create a new Transaction instance with details about the action. So I'm creating an entity inside a listener.



I've set up everything according to the documentation and created the listener based on this example.



The code (I believe) is relevant for my problem is following.



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


This works perfectly. However, the problem is when I add another field to the transaction entity. The user field inside Transaction entity has ManyToOne relation. Now when I try to set the user inside the preUpdateHandler, it leads to and undefined index error inside the UnitOfWork function of the Entity Manager.



Notice: Undefined index: 000000003495bf92000000001108e474 


The listener is now like this. I retreive the user based on the token that was sent with the request. Therefore, I inject the request stack and my custom user provider in the listener's constructor. I do not think this is the source of the problem. However, if necessary, I'll edit the post and add all the remaining code (rest of the listener, services.yaml and user provider).



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$request = $this->requestStack->getCurrentRequest();
$company = $this->userProvider->getUserByRequest($request);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


I do not understand why retreiving the flush with retrieval of another entity leads to that error. When searching for an answer I found that that many recommend not to use flush() inside the postUpdate cycle but rather in postFlush. However, this method is not defined for Entity listeners according to the documentation and if possible, I'd like to stick to such a listener and not an event listener.



Thank you for any help. I also include the transaction entity code just in case.



Transaction Entity



  <?php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use AppDoctrineUtilsMagicAccessors;
use AppEntityTTIdentifier;

/**
* @ORMEntity
* @ORMTable(name="transaction")
*/
class Transaction
{
use TIdentifier;
use MagicAccessors;

/**
* @ORMManyToOne(targetEntity="Item")
* @ORMJoinColumn(name="item_id", referencedColumnName="id", nullable=false)
*/
public $item;

/**
* @ORMColumn(type="decimal", length=14, precision=4, nullable=false)
*/
public $quantityChange;


/**
* @ORMColumn(type="datetime", nullable=true)
*/
private $createdTime;

/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @ORMJoinColumn(nullable=false)
*/
private $user;


public function __construct()
{
$this->createdTime = new DateTime();
}

/**
* @param mixed $quantityChange
*/
public function setQuantityChange(int $quantityChange): void
{
$this->quantityChange = $quantityChange;
}

/**
* @param mixed $createdTime
*/
public function setCreatedTime($createdTime): void
{
$this->createdTime = $createdTime;
}

/** @ORMPrePersist **/
public function onCreate() : void
{
$this->setCreatedTime(new DateTime('now'));
}

public function setUser(?User $user): self
{
$this->user= $user;

return $this;
}
}









share|improve this question























  • Have a look at this bundle?

    – BentCoder
    Jan 1 at 19:20
















2















I'm trying to record every change in quantity of a given item. For that purpose, I listen for a change of an Item entity and wish to create a new Transaction instance with details about the action. So I'm creating an entity inside a listener.



I've set up everything according to the documentation and created the listener based on this example.



The code (I believe) is relevant for my problem is following.



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


This works perfectly. However, the problem is when I add another field to the transaction entity. The user field inside Transaction entity has ManyToOne relation. Now when I try to set the user inside the preUpdateHandler, it leads to and undefined index error inside the UnitOfWork function of the Entity Manager.



Notice: Undefined index: 000000003495bf92000000001108e474 


The listener is now like this. I retreive the user based on the token that was sent with the request. Therefore, I inject the request stack and my custom user provider in the listener's constructor. I do not think this is the source of the problem. However, if necessary, I'll edit the post and add all the remaining code (rest of the listener, services.yaml and user provider).



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$request = $this->requestStack->getCurrentRequest();
$company = $this->userProvider->getUserByRequest($request);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


I do not understand why retreiving the flush with retrieval of another entity leads to that error. When searching for an answer I found that that many recommend not to use flush() inside the postUpdate cycle but rather in postFlush. However, this method is not defined for Entity listeners according to the documentation and if possible, I'd like to stick to such a listener and not an event listener.



Thank you for any help. I also include the transaction entity code just in case.



Transaction Entity



  <?php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use AppDoctrineUtilsMagicAccessors;
use AppEntityTTIdentifier;

/**
* @ORMEntity
* @ORMTable(name="transaction")
*/
class Transaction
{
use TIdentifier;
use MagicAccessors;

/**
* @ORMManyToOne(targetEntity="Item")
* @ORMJoinColumn(name="item_id", referencedColumnName="id", nullable=false)
*/
public $item;

/**
* @ORMColumn(type="decimal", length=14, precision=4, nullable=false)
*/
public $quantityChange;


/**
* @ORMColumn(type="datetime", nullable=true)
*/
private $createdTime;

/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @ORMJoinColumn(nullable=false)
*/
private $user;


public function __construct()
{
$this->createdTime = new DateTime();
}

/**
* @param mixed $quantityChange
*/
public function setQuantityChange(int $quantityChange): void
{
$this->quantityChange = $quantityChange;
}

/**
* @param mixed $createdTime
*/
public function setCreatedTime($createdTime): void
{
$this->createdTime = $createdTime;
}

/** @ORMPrePersist **/
public function onCreate() : void
{
$this->setCreatedTime(new DateTime('now'));
}

public function setUser(?User $user): self
{
$this->user= $user;

return $this;
}
}









share|improve this question























  • Have a look at this bundle?

    – BentCoder
    Jan 1 at 19:20














2












2








2








I'm trying to record every change in quantity of a given item. For that purpose, I listen for a change of an Item entity and wish to create a new Transaction instance with details about the action. So I'm creating an entity inside a listener.



I've set up everything according to the documentation and created the listener based on this example.



The code (I believe) is relevant for my problem is following.



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


This works perfectly. However, the problem is when I add another field to the transaction entity. The user field inside Transaction entity has ManyToOne relation. Now when I try to set the user inside the preUpdateHandler, it leads to and undefined index error inside the UnitOfWork function of the Entity Manager.



Notice: Undefined index: 000000003495bf92000000001108e474 


The listener is now like this. I retreive the user based on the token that was sent with the request. Therefore, I inject the request stack and my custom user provider in the listener's constructor. I do not think this is the source of the problem. However, if necessary, I'll edit the post and add all the remaining code (rest of the listener, services.yaml and user provider).



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$request = $this->requestStack->getCurrentRequest();
$company = $this->userProvider->getUserByRequest($request);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


I do not understand why retreiving the flush with retrieval of another entity leads to that error. When searching for an answer I found that that many recommend not to use flush() inside the postUpdate cycle but rather in postFlush. However, this method is not defined for Entity listeners according to the documentation and if possible, I'd like to stick to such a listener and not an event listener.



Thank you for any help. I also include the transaction entity code just in case.



Transaction Entity



  <?php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use AppDoctrineUtilsMagicAccessors;
use AppEntityTTIdentifier;

/**
* @ORMEntity
* @ORMTable(name="transaction")
*/
class Transaction
{
use TIdentifier;
use MagicAccessors;

/**
* @ORMManyToOne(targetEntity="Item")
* @ORMJoinColumn(name="item_id", referencedColumnName="id", nullable=false)
*/
public $item;

/**
* @ORMColumn(type="decimal", length=14, precision=4, nullable=false)
*/
public $quantityChange;


/**
* @ORMColumn(type="datetime", nullable=true)
*/
private $createdTime;

/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @ORMJoinColumn(nullable=false)
*/
private $user;


public function __construct()
{
$this->createdTime = new DateTime();
}

/**
* @param mixed $quantityChange
*/
public function setQuantityChange(int $quantityChange): void
{
$this->quantityChange = $quantityChange;
}

/**
* @param mixed $createdTime
*/
public function setCreatedTime($createdTime): void
{
$this->createdTime = $createdTime;
}

/** @ORMPrePersist **/
public function onCreate() : void
{
$this->setCreatedTime(new DateTime('now'));
}

public function setUser(?User $user): self
{
$this->user= $user;

return $this;
}
}









share|improve this question














I'm trying to record every change in quantity of a given item. For that purpose, I listen for a change of an Item entity and wish to create a new Transaction instance with details about the action. So I'm creating an entity inside a listener.



I've set up everything according to the documentation and created the listener based on this example.



The code (I believe) is relevant for my problem is following.



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


This works perfectly. However, the problem is when I add another field to the transaction entity. The user field inside Transaction entity has ManyToOne relation. Now when I try to set the user inside the preUpdateHandler, it leads to and undefined index error inside the UnitOfWork function of the Entity Manager.



Notice: Undefined index: 000000003495bf92000000001108e474 


The listener is now like this. I retreive the user based on the token that was sent with the request. Therefore, I inject the request stack and my custom user provider in the listener's constructor. I do not think this is the source of the problem. However, if necessary, I'll edit the post and add all the remaining code (rest of the listener, services.yaml and user provider).



ItemListener



// ...
private $log;
/** @ORMPreUpdate */
public function preUpdateHandler (Item $item, PreUpdateEventArgs $args)
{
$changeSet = $args->getEntityManager()->getUnitOfWork()->getEntityChangeSet($item)['quantity'];
$quantityChange = $changeSet[1] - $changeSet[0];

$transaction = new Transaction();
$transaction->setItem($item);
$transaction->setQuantityChange($quantityChange);

$request = $this->requestStack->getCurrentRequest();
$company = $this->userProvider->getUserByRequest($request);

$this->log = $transaction;
}

/** @ORMPostUpdate */
public function postUpdateHandler(Item $item, LifecycleEventArgs $args)
{
$em = $args->getEntityManager();
$em->persist($this->log);
$em->flush();
}


I do not understand why retreiving the flush with retrieval of another entity leads to that error. When searching for an answer I found that that many recommend not to use flush() inside the postUpdate cycle but rather in postFlush. However, this method is not defined for Entity listeners according to the documentation and if possible, I'd like to stick to such a listener and not an event listener.



Thank you for any help. I also include the transaction entity code just in case.



Transaction Entity



  <?php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use AppDoctrineUtilsMagicAccessors;
use AppEntityTTIdentifier;

/**
* @ORMEntity
* @ORMTable(name="transaction")
*/
class Transaction
{
use TIdentifier;
use MagicAccessors;

/**
* @ORMManyToOne(targetEntity="Item")
* @ORMJoinColumn(name="item_id", referencedColumnName="id", nullable=false)
*/
public $item;

/**
* @ORMColumn(type="decimal", length=14, precision=4, nullable=false)
*/
public $quantityChange;


/**
* @ORMColumn(type="datetime", nullable=true)
*/
private $createdTime;

/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @ORMJoinColumn(nullable=false)
*/
private $user;


public function __construct()
{
$this->createdTime = new DateTime();
}

/**
* @param mixed $quantityChange
*/
public function setQuantityChange(int $quantityChange): void
{
$this->quantityChange = $quantityChange;
}

/**
* @param mixed $createdTime
*/
public function setCreatedTime($createdTime): void
{
$this->createdTime = $createdTime;
}

/** @ORMPrePersist **/
public function onCreate() : void
{
$this->setCreatedTime(new DateTime('now'));
}

public function setUser(?User $user): self
{
$this->user= $user;

return $this;
}
}






symfony doctrine






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 30 '18 at 19:27









DanDan

856




856













  • Have a look at this bundle?

    – BentCoder
    Jan 1 at 19:20



















  • Have a look at this bundle?

    – BentCoder
    Jan 1 at 19:20

















Have a look at this bundle?

– BentCoder
Jan 1 at 19:20





Have a look at this bundle?

– BentCoder
Jan 1 at 19:20












1 Answer
1






active

oldest

votes


















0














I found out that the problem was that another instance of the entity manager was instantiated in the getUserByRequest() function, where I log that the user's token was used. Apart others, I created inside it a new manager, persisted the entry and flushed the result. However, the new entity manager does not know about the unit of work inside the other entity manager inside the listener. Hence the undefined index error.



I tried to omit the persist and the flush part inside the user getter function, but that was not enough. In the end I solved the problem by passing the given instance entity manager from inside the listener to the getter function. So basically, I ended up calling this from the preUpdateHandler function inside the listener.



$em = $args->getEntityManager();
$company = $this->userProvider->getUserByRequest($request, $em);


Hope this helps if you find yourself in a similar pickle.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53980735%2fsymfony-create-new-entity-inside-doctrine-entitylistener-with-manytoone-associa%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I found out that the problem was that another instance of the entity manager was instantiated in the getUserByRequest() function, where I log that the user's token was used. Apart others, I created inside it a new manager, persisted the entry and flushed the result. However, the new entity manager does not know about the unit of work inside the other entity manager inside the listener. Hence the undefined index error.



    I tried to omit the persist and the flush part inside the user getter function, but that was not enough. In the end I solved the problem by passing the given instance entity manager from inside the listener to the getter function. So basically, I ended up calling this from the preUpdateHandler function inside the listener.



    $em = $args->getEntityManager();
    $company = $this->userProvider->getUserByRequest($request, $em);


    Hope this helps if you find yourself in a similar pickle.






    share|improve this answer




























      0














      I found out that the problem was that another instance of the entity manager was instantiated in the getUserByRequest() function, where I log that the user's token was used. Apart others, I created inside it a new manager, persisted the entry and flushed the result. However, the new entity manager does not know about the unit of work inside the other entity manager inside the listener. Hence the undefined index error.



      I tried to omit the persist and the flush part inside the user getter function, but that was not enough. In the end I solved the problem by passing the given instance entity manager from inside the listener to the getter function. So basically, I ended up calling this from the preUpdateHandler function inside the listener.



      $em = $args->getEntityManager();
      $company = $this->userProvider->getUserByRequest($request, $em);


      Hope this helps if you find yourself in a similar pickle.






      share|improve this answer


























        0












        0








        0







        I found out that the problem was that another instance of the entity manager was instantiated in the getUserByRequest() function, where I log that the user's token was used. Apart others, I created inside it a new manager, persisted the entry and flushed the result. However, the new entity manager does not know about the unit of work inside the other entity manager inside the listener. Hence the undefined index error.



        I tried to omit the persist and the flush part inside the user getter function, but that was not enough. In the end I solved the problem by passing the given instance entity manager from inside the listener to the getter function. So basically, I ended up calling this from the preUpdateHandler function inside the listener.



        $em = $args->getEntityManager();
        $company = $this->userProvider->getUserByRequest($request, $em);


        Hope this helps if you find yourself in a similar pickle.






        share|improve this answer













        I found out that the problem was that another instance of the entity manager was instantiated in the getUserByRequest() function, where I log that the user's token was used. Apart others, I created inside it a new manager, persisted the entry and flushed the result. However, the new entity manager does not know about the unit of work inside the other entity manager inside the listener. Hence the undefined index error.



        I tried to omit the persist and the flush part inside the user getter function, but that was not enough. In the end I solved the problem by passing the given instance entity manager from inside the listener to the getter function. So basically, I ended up calling this from the preUpdateHandler function inside the listener.



        $em = $args->getEntityManager();
        $company = $this->userProvider->getUserByRequest($request, $em);


        Hope this helps if you find yourself in a similar pickle.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 3 at 15:46









        DanDan

        856




        856






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53980735%2fsymfony-create-new-entity-inside-doctrine-entitylistener-with-manytoone-associa%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Mossoró

            Error while reading .h5 file using the rhdf5 package in R

            Pushsharp Apns notification error: 'InvalidToken'