PHP原则2-如何使用Cascade选项自动保存一对多关系


PHP Doctrine 2 - How to save One To Many relationship automatically with Cascade options

我无法用Cascade保存条令2中的关系。在我的应用程序中,计算机有许多操作,而且一个操作可以属于许多不同的计算机。但我还有一个额外的属性"活动",用于指定每台计算机的活动操作。

我的表格如下:

CREATE TABLE IF NOT EXISTS computers (
      id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(50) NOT NULL UNIQUE,
      os VARCHAR(30) NOT NULL,
      date_creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      date_modification TIMESTAMP,
      online BOOLEAN NOT NULL DEFAULT FALSE,
      id_user_creation INT,
      id_user_modification INT DEFAULT NULL,
      CONSTRAINT fk_users_computers_creation FOREIGN KEY (id_user_creation) REFERENCES users(id),
      CONSTRAINT fk_users_computers_modification FOREIGN KEY (id_user_modification) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS actions (
      id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(50) NOT NULL UNIQUE,
      description TEXT,
      date_creation TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      date_modification TIMESTAMP,
      id_user_creation INT NOT NULL,
      id_user_modification INT DEFAULT NULL,
      CONSTRAINT fk_users_actions_creation FOREIGN KEY (id_user_creation) REFERENCES users(id),
      CONSTRAINT fk_users_actions_modification FOREIGN KEY (id_user_modification) REFERENCES users(id)
);
CREATE TABLE IF NOT EXISTS computers_actions (
      id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
      id_computer INT NOT NULL,
      id_action INT NOT NULL,
      active BOOLEAN NOT NULL DEFAULT FALSE,
      CONSTRAINT fk_computers FOREIGN KEY (id_computer) REFERENCES computers(id),
      CONSTRAINT fk_actions FOREIGN KEY (id_action) REFERENCES actions(id)
);

上面的代码只是我的数据库脚本的一部分,这个脚本受到了我当前问题的影响。我的实体如下:

计算机实体:

/**
 * @var ArrayCollection
 * @OneToMany(targetEntity="ComputerAction", mappedBy="computer", cascade={"persist"})
 */
private $actions;
public function __construct()
{
    $this->actions = new ArrayCollection();
}

行动实体:

/**
 * @var ArrayCollection
 * @OneToMany(targetEntity="ComputerAction", mappedBy="action", cascade={"persist"})
 */
private $computers;
public function __construct()
{
    $this->computers = new ArrayCollection();
}

关系,ComputerAction实体。我需要这个关系的一个属性,这就是为什么我没有使用ManyToMany注释。在这种情况下,一台计算机有许多ComputerAction,而一台ComputerAction只有一台计算机。Action也是如此。

/**
 * @var Computer
 * @ManyToOne(targetEntity="Computer", inversedBy="actions", cascade={"persist"})
 * @JoinColumn(name="id_computer", referencedColumnName="id")
 */
private $computer;
/**
 * @var Action
 * @ManyToOne(targetEntity="Action", inversedBy="computers", cascade={"persist"})
 * @JoinColumn(name="id_action", referencedColumnName="id")
 */
private $action;
/**
 * @var boolean
 * @Column(type="boolean")
 */
private $active;

这些属性有自己的getter和setter,正如您所注意到的,OneToMany属性具有Doctrine ArrayCollection类型。

在我的计算机上添加操作是在从ComputerController添加操作中完成的,如下所示:

// ComputerController, action add
$computer->setName($post['name']);
$computer->setOs($post['os']);
$computer->setOnline(false);
$computer->setUserOwner($this->getUserService()->find($this->retrieveUser()['id']));
foreach($post['action'] as $id_action) {
    $relation = new ComputerAction();
    $relation->setAction($this->getActionService()->find($id_action));
    $relation->setComputer($computer);
    $computer->setActions($relation);
}
if($computer = $this->getComputerService()->save($computer)) {
    $this->setMessage(sprintf('Computer [%s] added successfully!', $computer->getName()), MessageSkin::SUCCESS);
} else {
    $this->setMessage('The Computer could not be added. Try again later.', MessageSkin::DANGER);
}

在"计算机添加"视图中,我有一个带操作ID的"选择多个"。我得到了这些ID,在一个循环中,我创建了一个新的ComputerAction,将$action属性设置为包含该ID的action Entity。然后,我在$Computer属性中设置当前Computer,最后,我将ComputerAction的此实例添加到Computer Entity中的$actions ArrayCollection。

问题是:为什么ComputerAction实体没有被保存?

我尝试了许多不同的Cascade选项,但都没有成功。请帮忙!

谢谢!

Siipe

您应该记住,在任何关系中,Doctrine都有关系中的主实体和映射实体(从实体)。这是关于一对一,一对多,多对多的关系和其他。无论您写什么,都无法从从属实体保存主实体。

这也许对你有帮助。

我通过将$active属性设置为"false"解决了问题,因为它在数据库中不能为null。我真的不知道为什么会发生这种情况,因为它在数据库中是DEFAULTFALSE。条令没有警告我,也没有报告任何错误。