条令阵列类型字段未更新



我的问题与以下问题大致相同:

如何强制条令更新数组类型字段?

但由于某种原因,这个解决方案对我不起作用,所以我一定遗漏了一个细节,如果有人能向我指出,我会很高兴。

上下文是一个Symfony 5.2应用程序,使用的是Doctrine ^2.7。

实体类摘录:

class MyEntity {
// some properties
/**
* @var string[]
* @Groups("read")
* @ORMColumn(type="array")
* @AssertValid
*/
protected array $abbreviations = [];

public function getAbbreviations(): ?array
{
return $this->abbreviations;
}
//this is pretty much the same set-function as in the question I referenced
public function setAbbreviations(array $abbreviations)
{
if (!empty($abbreviations) && $abbreviations === $this->abbreviations) {
reset($abbreviations);
$abbreviations[key($abbreviations)] = clone current($abbreviations);
}
$this->abbreviations = $abbreviations;
}
public function addAbbreviation(LocalizableStringEmbeddable $abbreviation): self
{
foreach ($this->abbreviations as $existingAbbreviation) {
if ($abbreviation->equals($abbreviation)) {
return $this;
}
}
$this->abbreviations[] = $abbreviation;
return $this;
}
public function removeAbbreviation(LocalizableStringEmbeddable $abbreviation): self
{
foreach ($this->abbreviations as $i => $existingAbbreviation) {
if ($abbreviation->equals($existingAbbreviation)) {
array_splice($this->abbreviations, $i, 1);
return $this;
}
}
return $this;
}
}

但这些方法都没有被调用过(我也尝试过删除add-removeAbstration,只保留get/set(。

LocalizableStringEmbeddable是这样一个可嵌入的:

* @ORMEmbeddable
*/
class LocalizableStringEmbeddable
{
/**
* @var string|null
* @Groups("read")
* @ORMColumn(type="string", nullable=false)
*/
private ?string $text;
/**
* @var string|null
* @Groups("read")
* @ORMColumn(type="string", nullable=true)
* @AssertLanguage
*/
private ?string $language;
//getters/setters/equals/@AssertCallback
}

通过使用dd(…(,我可以进一步说,在提交的控制器中

$myEntity = $form->getData();

使用更新的数组生成一个正确填充的MyEntity,但我随后调用

$entityManager->persist($myEntity);
$entityManager->flush();

不会更改数据库。

我错过了什么?

编辑:我被要求提供关于我使用的类型的信息。这是一个基于此类的自定义类。所以从技术上讲,在事物的基础上,我使用的是集合类型。

abstract class AbstractLocalizableUnicodeStringArrayType extends AbstractType implements DataMapperInterface
{
abstract public function getDataClassName(): string;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('items', CollectionType::class, [
'entry_type' => LocalizedStringEmbeddableType::class,
'entry_options' => [
'data_class' => $this->getDataClassName(),
'attr' => ['class' => 'usa-item-list--item-box'],
],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
])
;
$builder->setDataMapper($this);
}
public function mapDataToForms($viewData, iterable $forms): void
{
$forms = iterator_to_array($forms);
if (null === $viewData) {
return;
}
if (!is_array($viewData)) {
throw new UnexpectedTypeException($viewData, "array");
}
$forms['items']->setData($viewData);
}
public function mapFormsToData(iterable $forms, &$viewData): void
{
$forms = iterator_to_array($forms);
$viewData = $forms['items']->getData();
}
}

当我发现这可以通过结合SO上另一篇文章的两个答案来解决(在我看来这是一种不合法的方式,但在出现更好的情况之前,我想说明这一点(:

https://stackoverflow.com/a/13231876/6294605

https://stackoverflow.com/a/59898632/6294605

这意味着将实体类中的preflush钩子与";假零钱";有问题的数组的。

请注意,在setter/adder/remover中进行虚假更改对我来说不起作用,因为在编辑现有实体时不会调用这些更改。在这种情况下,只有数组内更改对象的设置者才会被调用,因此Doctrine不会意识到数组本身发生了更改,因为似乎没有进行深入检查。

我想指出的另一个线程中没有说明的另一件事:

不要忘记用注释实体类

@ORMHasLifecycleCallbacks

否则,您的preflush钩子将不会执行。

相关内容

  • 没有找到相关文章

最新更新