我被要求收回几个月前离开公司的人的代码。 他开发了一个应用程序,允许一些人要求更改防火墙规则 当tou询问更改时,您可以选择/填写: 防火墙名称(对应防火墙接口) 港口 来源地址 目的地址 服务类型(TCP / UDP / ICMP)
数据库中有两个表:
Rule FW
---------- ---------
ID ID
Fw_Id Name
idrule Description
Port ----------
Source Address
Destination Adress
Service Type
----------
只有1个防火墙/规则和1个规则/防火墙
当我尝试保存表单时出现问题,doctrine尝试保存所有防火墙信息,而不仅仅是id,并告诉他们有一个唯一的密钥违规。 我搜索但无法弄清楚错误
规则实体:
<?php
namespace FWBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* Rule
*
* @ORM\Table(name="rule", uniqueConstraints={@ORM\UniqueConstraint(name="unique_fw_id", columns={"fw_id", "idrule"})})
* @ORM\Entity(repositoryClass="FwBundle\Repository\ruleRepository")
* @UniqueEntity(fields={"fw","idrule"}, message="Rule already exists")
*/
class Rule
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\OneToOne(targetEntity="FwBundle\Entity\fw")
* @ORM\JoinColumn(name="fw_id",referencedColumnName="id")
* @Assert\Valid()
*/
private $fw;
/**
* @var int
*
* @ORM\Column(name="idrule", type="integer")
*/
private $idrule;
FW实体:
<?php
namespace FWBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* fw
*
* @ORM\Table(name="fw")
* @ORM\Entity(repositoryClass="FWBundle\Repository\FwRepository")
* @UniqueEntity(fields="name", message="Firewall already exists.")
*/
class Fw
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;
RuleController:
public function AddAction($id,Request $request)
{
$namespace = 'FwBundle';
$em = thiss->getDoctrine()->getManager();
$repositoryRule = $em->getRepository($namespace.':Rule');
$repositoryFw = $em->getRepository($namespace.':Fw');
$rule = new rule();
$form = $this->createForm(RuleType::class, $rule,array('fw'=>$id));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$rule = $form->getData();
$em->persist($rule);
$em->flush();
}
}
答案 0 :(得分:0)
Rule
只能与一个Firewall
相关联,而一个Firewall
只能与一个Rule
相关联。您要做的是将多个Rule
链接到一个Firewall
。
您应该考虑将OneToOne
关系更改为ManyToOne
,因为防火墙可能有很多规则,错误应该消失(您必须先更新数据库架构)
如果您确定OneToOne
是您想要的那个,则如果防火墙已有一个规则,则不应在表单中创建新规则。
您的代码应与此类似:
public function AddAction($id,Request $request)
{
$namespace = 'FwBundle';
$em = thiss->getDoctrine()->getManager();
$repositoryRule = $em->getRepository($namespace.':Rule');
$repositoryFw = $em->getRepository($namespace.':Fw');
$rule = new rule(); // remove this line and change it with the two lines below
$fw = $repositoryFw->find($id); // assuming that id is the id of firewall
$rule = $fw->getRule() ? : new Rule(); // if Firewall has a rule entity then take it otherwise create a new one.
$form = $this->createForm(RuleType::class, $rule,array('fw'=>$id));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$rule = $form->getData();
$em->persist($rule);
$em->flush();
}
}