@dinya17

Почему не работает связь One-To-Many Doctrine в Postgress поле для связи в camelCase?

Суть проблемы следующая.
Есть 2 сущности и они связаны One-To-Many

class Shipping
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var ShippingStatus
     *
     * @ORM\Column(type="shipping_status")
     */
    private $status;

    /**
     * @var OrderId
     *
     * @ORM\Column(name="orderId", type="order_id", unique=true)
     */
    private $orderId;

    /**
     * @var \DateTimeImmutable
     * @ORM\Column(name="createDate", type="datetimetz_immutable")
     */
    private $createDate;

    /**
     * История
     *
     * @var Collection
     * @ORM\OneToMany(targetEntity="PointHistory", mappedBy="shipping", cascade={"all"}, orphanRemoval=true)
     *
     */
    private $pointsHistory;

    public function __construct(OrderId $orderId)
    {
        $this->orderId = $orderId;
        $this->createDate = new \DateTimeImmutable();
        $this->status = new ShippingStatus(ShippingStatus::IN_PROGRESS);
        $this->pointsHistory = new ArrayCollection();
    }

    /**
     * Добавить запись в историю.
     *
     * @param int                $pointId
     * @param \DateTimeImmutable $createDate
     * @param PointStatus        $pointStatus
     *
     * @throws ValidationError
     */
    public function addPointHistory(int $pointId, \DateTimeImmutable $createDate, PointStatus $pointStatus): void
    {
        $history = new PointHistory($pointId, $createDate, $this, $pointStatus);
        $this->pointsHistory->add($history);
    }

    /**
     * @return PointHistory[]
     */
    public function getHistory(): array
    {
        return $this->pointsHistory->toArray();
    }
}



class PointHistory
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var PointStatus
     *
     * @ORM\Column(type="point_status")
     */
    private $status;

    /**
     * @ORM\Column(name="pointId", type="integer")
     */
    private $pointId;

    /**
     * @var \DateTimeImmutable
     * @ORM\Column(name="createDate", type="datetimetz_immutable")
     */
    private $createDate;

    /**
     * @ORM\ManyToOne(targetEntity="driverApp\src\modules\Order\entities\shipping\Shipping", inversedBy="pointsHistory")
     * @ORM\JoinColumn(name="shippingId", nullable=false, onDelete="CASCADE")
     */
    private $shipping;

    public function __construct(int $pointId, \DateTimeImmutable $createDate, Shipping $shipping, PointStatus $status)
    {
        $this->pointId = $pointId;
        $this->shipping = $shipping;
        $this->createDate = $createDate;
        $this->status = $status;
    }

}


Возникала проблема с кавычками, но я ее решил вот таким магическим способом

class QuotedStrategy implements QuoteStrategy
{

    private function quote($token, AbstractPlatform $platform)
    {
        switch ($platform->getName()) {
            case 'postgresql':
            default:
                return $this->quoteIdentifier($token);
        }
    }

    private function quoteIdentifier($str)
    {
        if (strpos($str, '.') !== false) {
            $parts = array_map([$this, 'quoteSingleIdentifier'], explode('.', $str));

            return implode('.', $parts);
        }

        return $this->quoteSingleIdentifier($str);
    }

    private function quoteSingleIdentifier($str)
    {
        $c = '"';

        return $c . str_replace($c, $c . $c, $str) . $c;
    }

    // add quoting to appropriate methods
    public function getColumnName($fieldName, ClassMetadata $class, AbstractPlatform $platform)
    {
        return $this->quote($class->fieldMappings[$fieldName]['columnName'], $platform);
    }

    public function getTableName(ClassMetadata $class, AbstractPlatform $platform)
    {
        return $class->table['name'];
    }

    public function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform)
    {
        return $definition['sequenceName'];
    }

    public function getJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
    {
        return $this->quote($joinColumn['name'], $platform);
    }

    public function getReferencedJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
    {
        return $joinColumn['referencedColumnName'];
    }

    public function getJoinTableName(array $association, ClassMetadata $class, AbstractPlatform $platform)
    {
        return $association['joinTable']['name'];
    }

    public function getIdentifierColumnNames(ClassMetadata $class, AbstractPlatform $platform)
    {
        return $class->identifier;
    }

    public function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null)
    {
        return $platform->getSQLResultCasing($columnName . '_' . $counter);
    }
}


Но на этом проблемы не закончились. Сейчас при попытке получить данные связанной сущности PointHistory, вылетает ошибка
An exception occurred while executing 'SELECT t0.\"id\" AS id_1, t0.\"status\" AS status_2, t0.\"pointId\" AS pointid_3, t0.\"createDate\" AS createdate_4, t0.\"shippingId\" AS shippingid_5 FROM da_point_status_history t0 WHERE t0.shippingId = ?' with params [35]:\n\nSQLSTATE[42703]: Undefined column: 7 ERROR:  column t0.shippingid does not exist\nLINE 1: ...hippingid_5 FROM da_point_status_history t0 WHERE t0.shippin...\n                                                             ^\nHINT:  Perhaps you meant to reference the column \"t0.shippingId\"


вот тут подробнее

SELECT t0.\"id\" AS id_1, t0.\"status\" AS status_2, t0.\"pointId\" AS pointid_3, t0.\"createDate\" AS createdate_4, t0.\"shippingId\" AS shippingid_5 FROM da_point_status_history t0 WHERE t0.shippingId


Т.е. Доктрина при построении criteria не проставляет кавычки для названий полей, в моем случае shippingId

Как завтавить доктрину это делать? Я не нашел в документации ничего подобного.
Зато нашел код , где это все делается
BasicEntityPersister.php
$field = $sourceClass->fieldNames[$sourceKeyColumn];
            $value = $sourceClass->reflFields[$field]->getValue($sourceEntity);

            $criteria[$tableAlias . "." . $targetKeyColumn] = $value;
            $parameters[] = [
                'value' => $value,
                'field' => $field,
                'class' => $sourceClass,
            ];


Я уверен, что я не первый, что с этим столкнулся, но ответов пока не нашел нигде. Ткните куда смотреть.
  • Вопрос задан
  • 146 просмотров
Решения вопроса 1
@dinya17 Автор вопроса
В общем пока никто не ответил. Решил это все просто переименованием полей из верблюда в нижнее подчеркивание, все сразу взлетело. Но вот неужели по другому не решить?
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы