Symfony,Doctrine,合并不正常(虽然同一实体的持久性)

时间:2014-12-08 23:45:23

标签: php symfony inheritance doctrine

我对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)
     */

有人有想法或任何我可以在这里寻求帮助的资源吗?无法在网上找到任何具体信息。只有关于合并和持久的一般信息。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

不确定为什么合并不起作用,但我采取了另一条道路:

  • 按表单
  • 发布的ID获取授权
  • 然后使用表单数据($ form-> handleRequest($ request)
  • 更新此ID
  • 将更新的实体保留到数据库

这里是结果代码(我跳过了额外的函数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();
    }

    // ....
}