0

I want to create an identifier for my invoices, after I persist them. I'm using an auto generated ID in my identifier, so I have to use some postPersist callback to achieve this. However, my postPersist callback doesn't get fired.

Here is my AbstractInvoice entity:

<?php

namespace App\Invoice;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table("invoices")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="integer")
 * @ORM\DiscriminatorMap({
 *     "0"="Regular",
 *     "1"="Credit"
 * })
 */
abstract class AbstractInvoice
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @var int
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     * @var string
     */
    protected $identifier;

    /**
     * @ORM\PostPersist
     */
    protected function onPersist(): void
    {
        $this->identifier = '1' . str_pad($this->id, 5, '0', STR_PAD_LEFT);
    }
}

And here is my Regular invoice entity:

<?php

namespace App\Invoice;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class Regular extends AbstractInvoice
{
}

I create an instance of the regular invoice entity in my controller:

<?php

namespace App;

use App\Invoice\Regular;

class Controller
{
    public function handle(InvoiceRepository $invoices)
    {
        $invoice = new Regular();
        $invoices->add($invoice);
    }
}

Which uses this repository:

<?php

namespace App;

use App\Invoice\AbstractInvoice;
use Doctrine\ORM\EntityRepository;

class InvoiceRepository extends EntityRepository
{
    public function add(AbstractInvoice $invoice): void
    {
        $this->_em->persist($invoice);
        $this->flush();
    }
}

The invoice gets stored fine, only the onPersist method doesn't get fired. I already tried implementing the callback in the sub class (Regular), switching to a public method. No success there. Am I missing something?

Thank you!

  • 2
    Lifecycle methods needs to be `public`. – Jonnix Mar 21 '18 at 09:49
  • I used `die` inside the callback. But it get never reached. :) –  Mar 21 '18 at 09:49
  • Ha, it really was the `public` scoping! –  Mar 21 '18 at 09:51
  • https://stackoverflow.com/questions/7320425/doctrine-2-lifecyclecallbacks-with-abstract-base-class-are-not-called may also be relevant. – Jonnix Mar 21 '18 at 09:52
  • This is a typical showcase of how "not to use the ORM". You should stop relying on autogenerated identifiers as well as on magical lifecycle callbacks which even the author never uses. – Mike Doe Mar 21 '18 at 09:53
  • Yeah! Don't use those implemented and documented features! .... *sigh* – Jonnix Mar 21 '18 at 09:55
  • Yup, I see your point. However I'm refactoring some legacy code and using lifecycle callbacks seems to be best option, because depending on the ID is already in use (MySQL trigger). :) –  Mar 21 '18 at 09:56

0 Answers0