原则ORM:复合键和外键作为主键

问题描述

我正在尝试将组合键和外键作为在Doctrine ORM中工作的主键。我知道我正在尝试做的事情是可能的,因为它在此处进行了描述:https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/composite-primary-keys.html#composite-and-foreign-keys-as-primary-key。这正是我的用例:我有一些产品,一个订单和一个订单项。

但是,准则orm无法将此关系映射到数据库。当前的问题是,已注释的\Id主键中只有一个反映在mysql数据库上。因此,$ producto正确转换为producto_id到数据库,并且既是主键又是外键。但是,以相同方式注释的$orden属性在我的数据库中什么都不会出现。

enter image description here

这似乎很奇怪,因为当我第一次测试此功能时,我仅尝试使用两个属性之一,并且效果很好,但是,当同时注释两个属性时,元数据解析器似乎只能解析其中一个。此外,我试图通过忘记外键而只拥有一个复合主键(就像我以前使用过的那样)来将项目恢复到可用状态,但是现在解析器似乎甚至无法识别主键。例如,对于:

class ProductoOrden
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    private $idOrden;

    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    private $idProducto;

我得到:

bash-3.2$ php bin/console make:migration

In MappingException.php line 52:
                                                                                                
  No identifier/primary key specified for Entity "App\Entity\ProductoOrden". Every Entity must  
   have an identifier/primary key.                                                              
                                         

因此,我无法正确设置它或将其还原到以前的状态(这是最奇怪的状态)。

我要从头开始重新启动整个项目,因为我无法理解元数据解析的工作方式。我担心自己搞砸了,因为以前由于类似的问题,我已经手动擦除了'src \ Migrations'中的文件,而php bin/console doctrine:migrations:version --delete --all似乎没有用,或者我不知道如何正确使用它

结论:¿有人可以断言我尝试使用ProducoOrden进行的操作是否可行(也许我不了解文档示例)?有什么方法可以完全清除以前关于注释/架构元数据的缓存?

我已经看过orm:schema-tool了,但是我并没有真正了解如何正确配置它,或者为什么我必须在我的项目中已经全部使用bin/console工具的所有原因。

为了完整起见,我将显示所有三个涉及的类,但是主要问题是在ProductoOrden(订单项)中。

<?php

//Products
namespace App\Entity;

use App\Repository\ProductosRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * @ORM\Entity(repositoryClass=ProductosRepository::class)
 * @UniqueEntity("idProducto",message=" {producto {{ value }}}: llave primaria violada ")
*/
class Productos
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    private $id;    

    /**
     * @ORM\Column(type="string",length=255)
     */
    private $nombreProducto;

    /**
     * @ORM\Column(type="string",length=255)
     */
    private $descripcionProducto;

    /**
     * @ORM\Column(type="string",length=255)
     */
    private $urlImagen;

    /**
     * @ORM\Column(type="integer")
     */
    private $puntosProducto;

    public function getIdProducto(): ?int
    {
        return $this->idProducto;
    }

    public function getCodProducto(): ?int
    {
      return $this->idProducto;
    }

    public function setIdProducto(int $codProducto): self
    {
        $this->idProducto = $codProducto;

        return $this;
    }

    public function getNombreProducto(): ?string
    {
        return $this->nombreProducto;
    }

    public function setNombreProducto(string $nombreProducto): self
    {
        $this->nombreProducto = $nombreProducto;

        return $this;
    }

    public function getDescripcionProducto(): ?string
    {
        return $this->descripcionProducto;
    }

    public function setDescripcionProducto(string $descripcionProducto): self
    {
        $this->descripcionProducto = $descripcionProducto;

        return $this;
    }

    public function getUrlImagen(): ?string
    {
        return $this->urlImagen;
    }

    public function setUrlImagen(string $urlImagen): self
    {
        $this->urlImagen = $urlImagen;

        return $this;
    }

    public function getPuntosProducto(): ?int
    {
        return $this->puntosProducto;
    }

    public function setPuntosProducto(int $puntosProducto): self
    {
        $this->puntosProducto = $puntosProducto;

        return $this;
    }

    public function __toString(){
      $str = '{producto:'.$this->getIdProducto().',nombre: '.$this->getNombreProducto().'}';
      return $str;
    }
}


<?php
\\Orders
namespace App\Entity;

use App\Repository\OrdenesRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * @ORM\Entity(repositoryClass=OrdenesRepository::class)
 * @UniqueEntity("idOrden",message="{orden {{ value }}}: llave primaria violada")
 */
class Ordenes
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    private $id;


    /**
     * @ORM\Column(type="integer")
     */
    private $totalOrden;

    /**
     * @ORM\Column(type="string",length=255)
     */
    private $estado;

    /**
     * @ORM\OneToMany(targetEntity=ProductoOrden::class,mappedBy="orden",orphanRemoval=true)
     */
    private $productosOrden;

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

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getIdOrden(): ?int
    {
        return $this->idOrden;
    }

    public function setIdOrden(int $idOrden): self
    {
        $this->idOrden = $idOrden;

        return $this;
    }

    public function getTotalOrden(): ?int
    {
        return $this->totalOrden;
    }

    public function setTotalOrden(int $totalOrden): self
    {
        $this->totalOrden = $totalOrden;

        return $this;
    }

    public function getEstado(): ?string
    {
        return $this->estado;
    }

    public function setEstado(string $estado): self
    {
        $this->estado = $estado;

        return $this;
    }
    public function __toString(){
      $str = '{orden:'.$this->getIdOrden().'}';
      return $str;
    }

    /**
     * @return Collection|ProductoOrden[]
     */
    public function getProductosOrden(): Collection
    {
        return $this->productosOrden;
    }

    public function addProductosOrden(ProductoOrden $productosOrden): self
    {
        if (!$this->productosOrden->contains($productosOrden)) {
            $this->productosOrden[] = $productosOrden;
            $productosOrden->setOrden($this);
        }

        return $this;
    }

    public function removeProductosOrden(ProductoOrden $productosOrden): self
    {
        if ($this->productosOrden->contains($productosOrden)) {
            $this->productosOrden->removeElement($productosOrden);
            // set the owning side to null (unless already changed)
            if ($productosOrden->getOrden() === $this) {
                $productosOrden->setOrden(null);
            }
        }

        return $this;
    }
}


<?php
\\Order-items
namespace App\Entity;

use App\Repository\ProductoOrdenRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * @ORM\Entity(repositoryClass=ProductoOrdenRepository::class)
 * @UniqueEntity(fields={"idOrden","idProducto"},message="{prod. orden {{ value }}}: llave primaria violada")
 */
class ProductoOrden
{
    /*
     *  @ORM\Id
     * @ORM\ManyToOne(targetEntity=Ordenes::class,inversedBy="productosOrden")
     * @ORM\JoinColumn(nullable=false)
     */
    private $orden;

      /**
       * @ORM\Id
     * @ORM\ManyToOne(targetEntity=Productos::class)
     * @ORM\JoinColumn(nullable=false)
     */
    private $producto;

    /**
     * @ORM\Column(type="integer")
     */
    private $puntos;

    /**
     * @ORM\Column(type="integer")
     */
    private $cantidad;



    public function getId(): ?int
    {
        return $this->idOrden;
    }
   public function setIdOrden(int $idOrden): self
   {
    $this ->idOrden = $idOrden;

    return $this;

   }
    public function getIdProducto(): ?int
    {
        return $this->idProducto;
    }

    public function setIdProducto(int $idProducto): self
    {
        $this->idProducto = $idProducto;

        return $this;
    }

    public function getPuntos(): ?int
    {
        return $this->puntos;
    }

    public function setPuntos(int $puntos): self
    {
        $this->puntos = $puntos;

        return $this;
    }

    public function getCantidad(): ?int
    {
        return $this->cantidad;
    }

    public function setCantidad(int $cantidad): self
    {
        $this->cantidad = $cantidad;

        return $this;
    }

    public function __toString(){

      $str = '{productoOrden:'.$this->getId().','.$this->getIdProducto().'}';
      return $str;
    }

    public function getOrden(): ?Ordenes
    {
        return $this->orden;
    }

    public function setOrden(?Ordenes $orden): self
    {
        $this->orden = $orden;

        return $this;
    }
}


对于显示的类,它生成的迁移是

final class Version20200814210929 extends AbstractMigration
{
    public function getDescription() : string
    {
        return '';
    }

    public function up(Schema $schema) : void
    {
        // this up() migration is auto-generated,please modify it to your needs
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql','Migration can only be executed safely on \'mysql\'.');

        $this->addSql('ALTER TABLE producto_orden ADD puntos INT NOT NULL');
    }

    public function down(Schema $schema) : void
    {
        // this down() migration is auto-generated,'Migration can only be executed safely on \'mysql\'.');

        $this->addSql('ALTER TABLE producto_orden DROP puntos');
    }
}

如您所见,一些小的更改,例如更改属性作品的类型;但它似乎并没有采用id()和关联注释。

非常感谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...