我有一个控制器操作:
#[Route('/store', name: 'store', methods: 'POST')]
public function store(Request $request): Response
{
$myEntity = new MyEntity();
$form = $this->createForm(MyEntityFormType::class, $myEntity);
$form->handleRequest($request);
$form->submit($request->toArray());
if ($form->isSubmitted()) {
if ($form->isValid()) {
/** @var MyEntity $validatedMyEntity */
$validatedMyEntity = $form->getData();
$this->doctrine->persist($validatedMyEntity);
$this->doctrine->flush();
$this->doctrine->refresh($validatedMyEntity);
return $this->getJsonResponse($validatedMyEntity);
}
}
elseif (!$form->isSubmitted()) {
dd('not isSubmitted...');
}
当我调用端点时,我在
$this->doctrine->flush();
行收到以下错误消息:
{
"type": "https://tools.ietf.org/html/rfc2616#section-10",
"title": "An error occurred",
"status": 500,
"detail": "An exception occurred in the driver: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation \"ext_translations_id_seq\" does not exist\nCONTEXT: unnamed portal parameter $1 = '...'",
"class": "Doctrine\\DBAL\\Exception\\TableNotFoundException",
"trace": [
.
.
.
{
"namespace": "Doctrine\\DBAL",
"short_class": "Connection",
"class": "Doctrine\\DBAL\\Connection",
"type": "->",
"function": "lastInsertId",
"file": "/home/vagrant/Projects/tests/Trendency/vendor/doctrine/orm/lib/Doctrine/ORM/Id/IdentityGenerator.php",
"line": 48,
"args": []
},
.
.
.
]
}
有一件奇怪的事情,当我从命令调用它时,它运行良好。 我尝试启动
doctrine:shchame:validate
和 doctrine:shchame:update --force
命令,但没有任何效果。
额外
doctrine.orm.mappings
已在doctrine.yaml
中如下:
gedmo_translatable:
type: attribute
prefix: Gedmo\Translatable\Entity
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Translatable/Entity"
alias: GedmoTranslatable # (optional) it will default to the name set for the mapping
is_bundle: false
gedmo_translator:
type: attribute
prefix: Gedmo\Translator\Entity
dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Translator/Entity"
alias: GedmoTranslator # (optional) it will default to the name set for the mapping
is_bundle: false
形式为:
class MyEntityFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add(
'id',
UuidType::class,
[
'required' => false,
])
->add(
'title',
TextType::class,
[
'required' => true,
'constraints' => [
new NotBlank(['message'=>'Add Title!']),
new NotNull(['message'=>'Title cannot be null!']),
],
'invalid_message' => "Bad title type"
]
)
->add(
'description',
TextType::class,
[
'required' => true,
'constraints' => [
new NotBlank(['message' =>'Add Description!']),
new NotNull(['message' =>'Description cannot be null!']),
],
'invalid_message' => "Bad Description type"
]
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => MyEntity::class,
'csrf_protection' => false
]);
}
}
我怀疑,这个错误与
stof/doctrine-extensions-bundle
或id的uuid类型有关,但由于在它的存储库中找不到这个字符串,所以没有其他想法可以解决。
有谁有想法,如何解决?
感谢您提前提供帮助。
我找到了一个解决方法。
ext_translations_id_seq
名称是 stof/doctrine-extensions-bundle
gedmo_translator
特征中的序列名称。
我添加了动态表前缀逻辑,可以找到这里
不幸的是,这个表/序列不能与链接的 Doctrine 事件监听器很好地配合,所以我需要为 SEQUENCES 添加处理程序。
所以我也基于这个描述添加了一个SequencePrefixSubscriber。 之后,原始序列名称也带有前缀,除了
ext_translations_id_seq
之外,每个人都工作,因为持久期间的UnitOfWork会刷新该ClassMetaData,并在id生成期间搜索无前缀的序列名称。
为了处理它,我简单地为
Translation
和 AbstractTranslation
类创建了一个豁免案例,并使用此序列。这样以后就不会被覆盖,并且可以生成id。
这是完整的
loadClassMetadata()
方法:
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/** @var ClassMetadata $classMetadata */
$classMetadata = $eventArgs->getClassMetadata();
if ($classMetadata->isIdGeneratorSequence())
{
$newDefinition = $classMetadata->sequenceGeneratorDefinition;
$newDefinition['sequenceName'] = $this->prefix . $newDefinition['sequenceName'];
$classMetadata->setSequenceGeneratorDefinition($newDefinition);
$em = $eventArgs->getEntityManager();
if (isset($classMetadata->idGenerator)) {
$sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator(
$em->getConfiguration()->getQuoteStrategy()->getSequenceName(
$newDefinition,
$classMetadata,
$em->getConnection()->getDatabasePlatform()),
$newDefinition['allocationSize']
);
$classMetadata->setIdGenerator($sequenceGenerator);
}
}
if (in_array($classMetadata->getName(), [Translation::class, AbstractTranslation::class])) {
$sequenceName = $this->prefix . self::STOF_TRANSLATION_SEQ_NAME;
$idGenerator = new IdentityGenerator($sequenceName);
$classMetadata->setIdGenerator($idGenerator);
}
}
我只添加了 in_array 条件包裹的部分。
当然,展位订阅者和事件监听器应该在
services.yaml
中的服务索引下注册。