我在网络项目中使用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);
}
这并没有解决我的问题。很抱歉这个问题很长,很多可能相关的信息。
答案 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);
}
}