xml - PHP Doctrine:使用自定义 DBAL 类型的 embbebed 和实体 id 等相同类的问题
问题描述
我正在尝试在我的开发中实现 DDD 概念,但我遇到了 PHP Doctrine ORM 的问题。
首先,我想告诉你我的设计。我有一个实体调用 Order,一个 Order 有一个 ProductId 属性。所以,我的班级模型是这样的:
订单.php
<?php
final class Order
{
protected OrderId $id;
protected ProductId $product_id;
protected ProductName $name;
public function setProductId($product_id)
{
$this->product_id = $product_id;
}
public function getProductId()
{
return $this->product_id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}
产品.php
<?php
final class Product
{
protected ProductId $id;
protected ProductName $name;
protected $categories;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function assignToCategory(Category $category)
{
$this->categories[] = $category;
}
public function getCategory()
{
return $this->categories;
}
}
映射 XML 是:
订单.dcm.xml
<!-- config/xml/Product.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Order" table="orders">
<id name="id" type="order_id" column="id" length="36" />
<embedded name="product_id" class="ProductId" use-column-prefix="false" />
<embedded name="name" class="ProductName" use-column-prefix="false" />
</entity>
</doctrine-mapping>
产品.dcm.xml
<!-- config/xml/Product.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Product" table="products">
<id name="id" type="product_id" column="id" length="36" />
<embedded name="name" class="ProductName" use-column-prefix="false" />
<many-to-many target-entity="Category" field="categories" />
</entity>
</doctrine-mapping>
如您所见,对于 Order ORM 映射,我对 product_id 字段使用可嵌入的,另一方面,对于 Product ORM 映射,我对 id 字段使用自定义类型。这是产品的 id 自定义 DBAL 类型定义:
ProductIdType.php
<?php
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\StringType;
class ProductIdType extends StringType
{
public function getName(): string
{
return self::customTypeName();
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
$className = $this->typeClassName();
return new $className($value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value->value();
}
public static function customTypeName(): string
{
return 'product_id';
}
protected function typeClassName(): string
{
return ProductId::class;
}
}
这是需要 Order XML 映射的 ProductId XML 映射:
ProductId.dcm.xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="ProductId">
<field name="value" type="string" column="product_id" />
</embeddable>
</doctrine-mapping>
问题是当我尝试查找一个订单,然后在同一个脚本中尝试查找产品时。我认为问题在于同一类 ProductId 在同一脚本中用作可嵌入和自定义 DBAL 类型。但我希望有人能告诉我我是否正确,以及是否知道如何在不为 Order embedable 创建新类的情况下实现这一点。
我正在运行的脚本是:
show_product.php
<?php
require_once "bootstrap.php";
$id = $argv[1];
$order = $entityManager->find('Order', new OrderId($id));
if ($order === null) {
echo "No product found.\n";
exit(1);
}
echo print_r($order->getName());
$product = $entityManager->find('Product', new ProductId($id));
if ($product === null) {
echo "No product found.\n";
exit(1);
}
echo print_r($product->getName());
我的错误是:
PHP Notice: Undefined offset: 0 in /home/dani/www/dev/doctrine2-test/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php on line 769
PHP Stack trace:
PHP 1. {main}() /home/dani/www/dev/doctrine2-test/src/show_product.php:0
PHP 2. Doctrine\ORM\EntityManager->find() /home/dani/www/dev/doctrine2-test/src/show_product.php:16
PHP 3. Doctrine\ORM\UnitOfWork->getSingleIdentifierValue() /home/dani/www/dev/doctrine2-test/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:419
PHP 4. Doctrine\ORM\Mapping\ClassMetadata->getIdentifierValues() /home/dani/www/dev/doctrine2-test/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:3065
如果有人想查看所有代码,这里是 Github 存储库:https ://github.com/daf111/doctrine2-test
非常感谢您的宝贵时间!
解决方案
推荐阅读
- javascript - 如何将评估返回的变量传递给 Nightmare.js 中的另一个评估
- spring-boot - 使用 Spring 中的 JpaRepository 从 Kotlin(Springboot)中的表中删除一行的正确方法是什么?
- html - Bootstrap:列元素在其他列上溢出
- reactjs - React - < Input> 值未在 onChange 事件上更新
- android - 在构造函数中创建具有 Android 上下文作为参数的单例类
- vb.net - System.Net.WebException:“远程服务器返回错误:(463)。”
- css - 重新创建/复制 Twitter 的 @username 信息模态框
- security - 隐藏threejs软件后端工作的自定义格式
- opencv - 如何为 DataGenerator keras 使用自定义图像加载器?
- excel - 为什么在尝试将布尔类型的变量传递给 txtBox_Exit() 事件时出现类型不匹配错误?