Doctrine2 + ZF2:通过连接表与元数据具有多对多关联的水合实体

时间:2016-03-08 15:36:28

标签: php doctrine-orm zend-framework2 hydration

我有两个实体RentalItemItem通过包含一些元数据的连接表与Rental相关联,以便连接表有效地成为第三个实体RentedItem

由于RentedItem可以通过其关联的RentalItem进行标识,因此它不需要自己的ID,而是使用由这两个外键组成的复合键作为主键代替。

/**
 * @ORM\Entity
 */
class Rental
{
    // ...
    /**
     * @ORM\OneToMany(targetEntity="RentedItem", mappedBy="rental", cascade={"all"})
     * @var ArrayCollection $rented_items
     */
    protected $rented_items;
    // ...
}

/**
 * @ORM\Entity
 */
class Item
{
    // ...
    // Note: The Item has no notion of any references to it.
}

/**
 * @ORM\Entity
 */
class RentedItem
{
    // ...
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Rental", inversedBy="rented_items")
     * @var Rental $rental
     */
    protected $rental;
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Item")
     * @var Item $item
     */
    protected $item;
    /**
     * @ORM\Column(type="boolean")
     * @var bool $is_returned
     */
    protected $is_returned = false;
    // ...
}

可以通过RESTful API创建或更改Rental,包括一些相关对象。相应的控制器使用ZF2 DoctrineModule的DoctrineObject水合器来使用给定的表单数据来水合租赁对象。新数据作为

形式的数组传递给水化器
$data = [
    // We only use the customer's ID to create a reference to an
    // existing customer. Altering or creating a customer via the
    // RestfulRentalController is not possible
    'customer' => 1, 
    'from_date' => '2016-03-09',
    'to_date' => '2016-03-22',
    // Rented items however should be alterable via the RestfulRentalController,
    // because they don't have their own API. Therefore we pass
    // the complete array representation to the hydrator
    'rented_items' => [
        [
            // Again, just as we did with the customer, 
            // only use the referenced item's ID, so that
            // changing an item is not possible
            'item' => 6, 
            'is_returned' => false
            // NOTE: obviously, the full array representation of
            // a rented item would also contain the 'rental' reference,
            // but since this is a new rental, there is no id yet, and
            // the reference should be implicitly clear via the array hirarchy
        ],
        [
            'item' => 42,
            'is_returned' => false
        ]
    ]
];

通常,水化器可以正确设置参考,即使对于全新的实体和新关系也是如此。但是,由于这种复杂的关联,Rental的保湿失败了。代码

$hydrator = new \DoctrineModule\Stdlib\Hydrator\DoctrineObject($entity_manager);
$rental = $hydrator->hydrate($data, $rental);

因以下异常而失败

Doctrine\ORM\ORMException

File:

    /vagrant/app/vendor/doctrine/orm/lib/Doctrine/ORM/ORMException.php:294

Message:

    The identifier rental is missing for a query of Entity\RentedItem

我是否必须手动设置租借物品的参考?或者这可能是由错误的配置引起的?

0 个答案:

没有答案