我对Symfony / Doctrine的行为感到困惑。
我有一个表单,在提交时,将数据发送回控制器。如果表单包含新实体或已在数据库中具有id的数据(之前已加载到表单中)的数据,此控制器将检查:
if ($form->isValid()) {
if ($sup->getId() > 0) {
return $this->editUserAction($sup);
} else {
return $this->addUserAction($sup);
}
}
调用的两个函数几乎相等。它们仅在命令持久性与合并性方面不同。有趣的是,持久化写入了一个在合并时未写入的字段:
有一个继承:
供应商扩展公司, 公司延伸联系
ORM-wise公司是一个MappedSuperclass,也是一个MappedSuperclass(都是抽象的)。这是因为供应商是公司的专业化,这也是通用联系人的专业化。
来自供应商的所有值和从联系人继承的值都将被写入数据库(始终)。 只有来自公司的所有值都会在调用persist时写入数据库,但从不调用merge时。这些课程中没有被覆盖的属性。
它是发送数据的相同形式(为此创建了FormType:TypeSupplier)。它是相同的类等。定义了getter和setter(否则表单无法设置持久值)。即使我输入相同的数据,一次从头开始,一次更改另一个实体。
还有一点:数据库中的值不会被null覆盖。它只是不会改变,而所有其他值将在合并时发生变化。
不确定此信息是否有帮助:phpStorm中的调试器显示该值在调用merge的行中的变量$ sup中设置:" Whizzpm \ Bundle \ Entity \ Contact \ Company * name1 =& #34;测试值"
public function addUserAction(Supplier $sup)
{
$em = $this->getDoctrine()->getManager();
$em->perist($sup);
$em->flush();
return $this->redirect($this->generateUrl('suppliers_show'));
}
public function editUserAction(Supplier $sup)
{
$em = $this->getDoctrine()->getManager();
$em->merge($sup);
$em->flush();
return $this->redirect($this->generateUrl('suppliers_show'));
}
以下是实体类公司的摘录,其中包含在调用merge时未写入数据库的两个值:
/**
* Class Company
* @package Whizzpm\Bundle\Entity\Contact
* @ORM\MappedSuperclass
*/
abstract class Company extends Contact {
/**
* @var string
* @ORM\Column(type="string", length=60, nullable=false)
*/
private $name1;
/**
* @var string
* @ORM\Column(type="string", length=60, nullable=true)
*/
private $name2;
/**
* @var integer
* @ORM\Column(type="integer", name="employees", nullable=true)
*/
有人有想法或任何我可以在这里寻求帮助的资源吗?无法在网上找到任何具体信息。只有关于合并和持久的一般信息。
感谢您的帮助!
答案 0 :(得分:0)
不确定为什么合并不起作用,但我采取了另一条道路:
这里是结果代码(我跳过了额外的函数addUserAction / editUserAction,因为两者现在一次性工作:
public function showSuppliersAction(Request $request)
{
$sup = null;
if($supplier = $request->request->get('supplier')) {
if(isset($supplier['id'])) {
$sup = $this->getDoctrine()
->getRepository('WhizzpmBundle:Supplier\Supplier')
->findOneById($supplier['id']);
}
}
if(!$sup) {
$sup = new Supplier();
}
$form = $this->createForm(new SupplierType(), $sup);
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($form->isValid()) {
$em->persist($sup);
$em->flush();
}
// ....
}