在我使用 Doctrine ORM 2.7.0 的 Symfony 4 应用程序中,我得到了一个实体
Product
,它是外部包/系统(Akeneo 5)的一部分,我不能直接修改。由于我需要向其添加一个属性 (stock
),因此我创建了一个类,即 extends
这个实体,并将其注册以代替原来的属性:
src/Tpg/Bundle/AkeneoTpgBundle/Entity/Product.php
<?php
namespace Tpg\Bundle\AkeneoTpgBundle\Entity;
use Akeneo\Pim\Enrichment\Component\Product\Model\Product as AkeneoProduct;
class Product extends AkeneoProduct
{
private $stock;
// access methods ...
}
config/services/services.yml
parameters:
pim_catalog.entity.product.class: 'Tpg\Bundle\AkeneoTpgBundle\Entity\Product'
src/Tpg/Bundle/AkeneoTpgBundle/Resources/config/doctrine/Product.orm.yml
Tpg\Bundle\AkeneoTpgBundle\Entity\Product:
type: entity
table: pim_catalog_product
fields:
stock:
type: integer
nullable: false
但现在我遇到了别名的问题。在
SELECT
语句中,列和条件使用不同的别名:
SELECT
t1.id AS id_2,
t1.is_enabled AS is_enabled_3,
...
FROM pim_catalog_product t1
WHERE t0.id = 1207
这当然会导致错误。
发生这种情况的机制如下:
Doctrine\ORM\Persisters\Entity\BasicEntityPersister#getSelectSQL(...)
中,称为 getSelectConditionSQL(...)->getSelectConditionStatementSQL(...)->getSelectConditionStatementColumnSQL(...)
。getSQLTableAlias(...)
与 $this->class->fieldMappings[$field]['inherited']
称为 $className
参数。这就是原始实体的类名。getSQLTableAlias(...)
检查传递的$className
是否已在其内部列表中。事实并非如此,因此它将别名设置为 't' . $this->currentPersisterContext->sqlAliasCounter
(t0
) 并增加计数器。BasicEntityPersister#getSelectSQL(...)
中调用 getSelectColumnsSQL(...)->getSelectColumnSQL(...)
。getSQLTableAlias(...)
与 $this->className
称为 $className
参数。这就是 custom 实体的类名。getSQLTableAlias(...)
检查传递的$className
是否已在其内部列表中。不再是这样,因此它将别名设置为 't' . $this->currentPersisterContext->sqlAliasCounter
,现在的结果是 t1
。 -- 现在我们得到了这种不匹配:列的 t1
别名和条件的 t0
。getSelectConditionStatementColumnSQL()
。但这个地方在多个 Doctrine 版本中都保持不变,所以这不会是一个错误。这背后的意义是什么?..
如何让它正常工作?