【问题标题】:Modifying Doctrine collections doesn't affect database tables修改 Doctrine 集合不会影响数据库表
【发布时间】:2011-02-05 17:47:36
【问题描述】:

我对 Doctrine 2 完全陌生(对 ORM 也是如此),我在更新集合时遇到了问题。我觉得这是一个典型的菜鸟问题。

我需要客户和房东。每个主机都分配给某个客户,每个客户可以有多个主机。我的(简化)类如下:

/**
 * @Entity @Table(name="Customers")
 */
class Customer
{
    /** @Id @Column(type="integer") @GeneratedValue */
    private $id;

    /** @OneToMany(targetEntity="Host", mappedBy="cust_id") */
    private $hosts = null;

    public function __construct()
    {
      $this->hosts = new ArrayCollection();
    }

    public function addHost( $host )
    {
      $this->hosts[] = $host;
    }

    // plus getters/setters...
}

/**
 * @Entity @Table(name="Hosts")
 */
class Host
{
    /** @Id @Column(type="integer") @GeneratedValue */
    private $id;

    /** @ManyToOne(targetEntity="Customer", inversedBy="hosts") */
    private $cust_id;

    // plus getters/setters...
}

我的数据库(SQLite)表如下:

客户:id,...

主机:id、cust_id_id、...

我可以使用以下代码创建新客户和主机:

$customer = new Customer();
$em->persist( $customer );
$em->flush();

但是当我尝试向客户添加一些主机时,使用以下代码:

$customer = ... // obtain a customer object - that works.
$host = ... // obtain a host object - that works.
$customer->addHost($host);
$em->persist($customer);
$em->flush();

什么都没有发生。我的意思是我的数据库中没有任何变化(受影响主机的 cust_id_id 仍然为空)。我想为某个消费者添加一个新主机,并在 Hosts 表中正确设置 cust_id_id 列。

我做错了什么?


更新:

我认为 OneToMany 关系必须是反面,因为将其声明为拥有方会导致我的学说抱怨未知选项“inversedBy”。所以我决定把Customer作为inverse,Host作为owner,修改Customer->addHost方法如下:

public function addHost( $host )
{
  $host->setCustomerId( $this->id );
  $this->hosts[] = $host;
}

现在,调用 $em->flush() 后出现以下错误:

未捕获的异常 'InvalidArgumentException' 与 message '找到一个新实体 通过一段不 配置为级联持久化 操作:@。明确坚持 新实体或配置级联 坚持操作 关系。'

【问题讨论】:

  • IMO,您应该将 Host::$cust_id 重命名为 Host::$customer
  • 这和this question非常相似

标签: php orm doctrine-orm


【解决方案1】:

您将 Customer#hosts 定义为反面。将数据保存到数据库时只考虑拥有方。请参阅有关此问题的手册章节。

http://www.doctrine-project.org/docs/orm/2.0/en/reference/association-mapping.html#owning-side-and-inverse-side

在您的情况下,如果您希望使用 Customer#addHosts 而不是 Host#addCustomer,则必须在两个实体上切换“mappedBy”和“inversedBy”关键字。

【讨论】:

猜你喜欢
  • 2017-12-03
  • 2015-12-04
  • 2016-04-28
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
相关资源
最近更新 更多