月生成的doctrine2实体编号

时间:2019-11-22 22:16:30

标签: doctrine-orm doctrine entity symfony4

我有一个发票实体,我想在其中创建给定月份内的后续编号。
实体代码:

/**
 * Class Invoice
 * @package App\Entity
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Invoice
{
(...)
   /**
     * @var int
     * @ORM\Column(type="integer")
     */
    private $year;

    /**
     * @var int
     * @ORM\Column(type="integer")
     */
    private $month;

    /**
     * @var int
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="App\Helper\InvoiceNumberGenerator")
     */
    private $counter;
(...)
    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function numberGenerator()
    {
        if ($this->getYear() === null) {
            $this->setYear(date('Y'));
            $this->setMonth(date('m'));
        }
    }

App \ Helper \ InvoiceNumberGenerator代码为:

<?php

namespace App\Helper;


use App\Entity\Invoice;
use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Exception;

class InvoiceNumberGenerator extends AbstractIdGenerator
{

    /**
     * Generates an invoice number
     *
     * @param EntityManager $em
     * @param Invoice $entity
     * @return mixed
     * @throws Exception
     */
    public function generate(EntityManager $em, $entity)
    {
        if (!$entity instanceof Invoice) {
            throw new Exception('Generator służy tylko do generowania numerów faktur.');
        }
        /** @var ObjectRepository | EntityRepository $invoiceRepository */
        $invoiceRepository = $em->getRepository(Invoice::class);

        /** @var Invoice $lastInvoice */
        $lastInvoice = $invoiceRepository->findOneBy(
            array(
                'year' => $entity->getYear(),
                'month' => $entity->getMonth()
            ),
            array(
                'counter' => 'desc'
            )
        );

        if (empty($lastInvoice)) {
            return 1;
        }

        return $lastInvoice->getCounter() + 1;
    }
}

当我转储$lastInvoice时,它显示:

Invoice {#5522 ▼
  -id: 1
  -generated: false
  -fileName: "example"
  -year: 2019
  -month: 11
  -counter: 1
  -name: "AG"
  -company: "Gall"
  -address: "Street 1"
  -address2: "Gliwice"
  -nip: "6314567890"
  -reservation: Reservation {#5855 ▶}
  -date: null
}

所以看起来生成器可以正确选择最后一个,但是尽管如此,在尝试创建新发票时还是出现了错误:

  

SQLSTATE [23000]:违反完整性约束:1048列“计数器”   不能为空

有人建议我做错了什么吗?

1 个答案:

答案 0 :(得分:1)

仅当列也用int main(int argc, char *argv[]){//argv[1] first item i need int i; int *parseInt; srand(time(NULL)); List MyCostumers;//costumer list by their arrival time(imagine they outside the shop) List InCoffe;// the q inside the coffee shop List ServeList;// costumers that are served now Robots MyRobots; parseInt = parseInput(argc,argv); MyCostumers = createCostumerList(parseInt);//costumers created ServeList = CreateListPQ();//currently served costumers InCoffe = initialiseSimulator(parseInt,MyRobots);//waiting q newCostumer(InCoffe,MyCostumers,ServeList); printf("%d ",MyRobots->robotNum); printf("%d ",MyRobots->workingRobots); printf("%d ",MyRobots->robots[1]); DisplayListPQ(InCoffe); return 0; } List initialiseSimulator(int parseInt[],Robots MyRobots){ List inCoffeeQ = CreateListPQ(); MyRobots = malloc(sizeof(struct robotSlave)); struct Node* dummy; dummy = (struct Node *) malloc(sizeof(struct Node)); dummy->next = NULL; MyRobots->head = dummy; MyRobots->tail = dummy; MyRobots->robotNum = parseInt[3]; MyRobots->workingRobots = 0; MyRobots->robots = calloc(sizeof(int),MyRobots->robotNum); return inCoffeeQ; } typedef struct ListRecord* List; typedef struct Node* Node; typedef struct robotSlave* Robots; 标记时才调用@CustomIdGenerator注释。来自docs

  

此批注允许您指定用户提供的类以生成标识符。仅当同时指定@Id和@GeneratedValue(strategy =“ CUSTOM”)时,此批注才有效。

id始终是一种特殊的事物,因此有时在插入之前必须是完美的。要解决您的问题(因为计数器不是id列),您可以改用lifecycle events(可能是prePersist),并在事件侦听器/订阅者中使用event's entity manager来运行查询。