我有一个发票实体,我想在其中创建给定月份内的后续编号。
实体代码:
/**
* 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列“计数器” 不能为空
有人建议我做错了什么吗?
答案 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来运行查询。>