symfony doctrine persist update / insert

时间:2018-04-17 20:30:03

标签: php symfony doctrine

我在网络项目中使用symfony和doctrine。我有一系列实体,其中一个是修订版,修订版则有一系列一对多的关系。我正在尝试编辑修订并将其另存为新行(意味着我想插入)。但是,当我坚持学说更新现有行而不是插入时。为了解决这个问题,我明确地将revId(表主键)更改为不同但仍然更新。如果id不同,Persist应该知道更新,所以有人知道它为什么会更新。

注意:我使用包含一系列集合类型表单的嵌入表单填充修订实体。

修订实体

/**
 * @ORM\Entity
 * @ORM\Table(name="policies_revisions")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\RevisionRepo")
 */
class PoliciesRevisions
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue
 */
private $revId;

/**
 * @ORM\OneToOne(targetEntity="Policies", inversedBy="revisions", cascade={"persist"})
 * @ORM\JoinColumn(name="policy_id", referencedColumnName="policy_id")
 */
private $policies;

/**
 * @ORM\OneToMany(targetEntity="PoliciesApplicability", mappedBy="revision", cascade={"persist"})
 */
private $applicability;

/**
 * @ORM\OneToMany(targetEntity="PoliciesAuthority", mappedBy="revision", cascade={"persist"})
 */
private $authority;

/**
 * @ORM\OneToMany(targetEntity="PoliciesDefinitions", mappedBy="revision", cascade={"persist"})
 */
private $definition;

/**
 * @ORM\OneToMany(targetEntity="PoliciesExclusions", mappedBy="revision", cascade={"persist"})
 */
private $exclusions;

/**
 * @ORM\OneToMany(targetEntity="PoliciesInterpretation", mappedBy="revision", cascade={"persist"})
 */
private $interpretation;

/**
 * @ORM\OneToMany(targetEntity="PoliciesPolicy", mappedBy="revision", cascade={"persist"})
 */
private $policy;

/**
 * @ORM\OneToMany(targetEntity="PoliciesPurposes", mappedBy="revision", cascade={"persist"})
 */
private $purpose;

/**
 * @ORM\OneToMany(targetEntity="PoliciesResponsibilities", mappedBy="revision", cascade={"persist"})
 */
private $responsibilities;

/**
 * @ORM\OneToMany(targetEntity="PoliciesSanctions", mappedBy="revision", cascade={"persist"})
 */
private $sanctions;

/**
 * @ORM\OneToMany(targetEntity="PoliciesProcedures", mappedBy="revision", cascade={"persist"})
 */
private $procedures;

/**
 * @ORM\Column(type="integer")
 */
private $policyId;

/**
 * @ORM\Column(type="integer")
 */
private $submittedDatetime;
/**
 * @ORM\Column(type="integer")
 */
private $publishedDatetime;
/**
 * @ORM\Column(type="integer")
 */
private $createdByUserId;
/**
 * @ORM\Column(type="integer")
 */
private $revNum;
/**
 * @ORM\Column(type="boolean")
 */
private $published;

public function __construct()
{
    $this->applicability = new ArrayCollection();
    $this->authority = new ArrayCollection();
    $this->definition = new ArrayCollection();
    $this->exclusions = new ArrayCollection();
    $this->interpretation = new ArrayCollection();
    $this->policy = new ArrayCollection();
    $this->procedures = new ArrayCollection();
    $this->purpose = new ArrayCollection();
    $this->responsibilities = new ArrayCollection();
    $this->sanctions = new ArrayCollection();
}

其他实体(均遵循此表格)

/**
 * @ORM\Entity
 * @ORM\Table(name="policies_applicability_two")
 */
class PoliciesApplicability
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue
 */
private $appId;

/**
 * @ORM\Column(type="integer")
 */
private $revId;

/**
 * @ORM\OneToOne(targetEntity="PoliciesRevisions", inversedBy="applicability", cascade={"persist"})
 * @ORM\JoinColumn(name="rev_id", referencedColumnName="rev_id")
 */
private $revision;

/**
 * @ORM\Column(type="string")
 */
private $applicabilityText;

public function getAppId()
{
    return $this->appId;
}
public function setAppId($appId)
{
    $this->appId = $appId;
}

public function getRevId()
{
    return $this->revId;
}
public function setRevId($revId)
{
    $this->revId = $revId;
}

public function getApplicabilityText()
{
    return $this->applicabilityText;
}
public function setApplicabilityText($applicabilityText)
{
    $this->applicabilityText = $applicabilityText;
}

public function getRevision()
{
    return $this->revision;
}
public function setRevision($revision)
{
    $this->revision = $revision;
}
}

控制器

if ($form->isSubmitted() && $form->isValid()) {

        $entityManager = $this->getDoctrine()->getManager();
        $maxRevNum = $this->getDoctrine()->getRepository(PoliciesRevisions::class)->findMaxRevNum($policyId);
        if ($maxRevNum[0][1] == NULL)
            $task->setRevNum(1);
        else
            $task->setRevNum($maxRevNum[0][1] + 1);

        $nextRevId = $this->getDoctrine()->getRepository(PoliciesRevisions::class)->findMaxRevId($policyId);
        if ($nextRevId[0][1] != NULL)
            $task->setRevId($nextRevId[0][1] + 1);

        $pol = $this->getDoctrine()->getRepository(Policies::class)->findOneBy(['policyId'=>$policyId]);
        $task->setPolicyId($policyId);
        $task->setPolicies($pol);
        $task->setPublished(0);
        $task->setPublishedDatetime(0);

        foreach ($task->getApplicability() as $i=>$object) {
            $object->setRevision($task);
            //print_r($task->getApplicability());
        }
        foreach ($task->getAuthority() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getDefinition() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getExclusions() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getInterpretation() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getPolicy() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getProcedures() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getPurpose() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getResponsibilities() as $i=>$object) {
            $object->setRevision($task);
        }
        foreach ($task->getSanctions() as $i=>$object) {
            $object->setRevision($task);
        }

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

修订表格

$builder->add('applicability', CollectionType::class, array(
        'entry_type' => ApplicabilityForm::class,
        'entry_options' => array('label' => false),
        'allow_add' => true,
        'allow_delete' => true,
        'by_reference' => true,
        'required' => false
    ));

其他表格(遵循相同的模板)

class ApplicabilityForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $MainEntity = $builder->getData();
    $builder
        ->add('applicabilityText', TextareaType::class, array(
            'required' => false,
            'label' => 'Applicability',
            'attr' => array('class' => 'col-sm-10')
        ));
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class'=>PoliciesApplicability::class,
    ));
}
}

更新:我修正了一些问题,通过更改刷新线我停止了更新的旧行,这就是我想要的。

$entityManager->flush($task);

修订表正在添加一个包含我期望的所有信息的新行。但是,没有行添加到具有与修订相关的外键的表中。我尝试通过使用我用于将表单填充到ArrayCollections的持久集合来解决这个问题,这就是我做的方式

foreach ($task->getApplicability() as $i=>$object) {
            $object->setRevision($task);
            $task->setApplicability(new ArrayCollection());
            $task->getApplicability()->add($object);
        }

这并没有解决我的问题。很抱歉这个问题很长,很多可能相关的信息。

2 个答案:

答案 0 :(得分:1)

您不应更改现有实体,然后尝试将其另存为新实体。您应该创建实体的新实例,使用新值填充它,然后保存:

,而不是这样
  if ($form->isSubmitted() && $form->isValid()) {

      $newTask = new Task();
      ...
      $newTask->setPolicyId($policyId);
      $newTask->setPolicies($pol);
      $newTask->setPublished(0);
      $newTask->setPublishedDatetime(0);
      ...
      $entityManager->persist($newTask);
      $entityManager->flush();
  }

答案 1 :(得分:0)

您无法简单地更改primaryKey,您的实体将附加到doctrine。 您可以使用以下命令分离您的实体:

$em->detach($entity);

然后做你的关系并坚持下去。

或者如果您使用表单,我认为使用新对象构建表单更好,不要使用请求获得的对象。

PS:不要这样做onetomanys关系,定义bidirectionnals关系和/或在你的实体中定义新的setter,如:

public function setExclusions($exclusions){
    foreach ($exclusions as $exclusion) {
        $exclusion->setRevision($this);
    }
}