【问题标题】:Doctrine - How to create inverse relation?教义 - 如何创建反比关系?
【发布时间】:2015-05-20 11:02:53
【问题描述】:

在 symfony 中,我从已经创建的数据库中创建了两个实体。我在 symfony 的控制台中使用了以下命令:

php app/console doctrine:mapping:import --force IDFrontendBundle xml
php app/console doctrine:mapping:convert annotation ./src
php app/console doctrine:generate:entities IDFrontendBundle

产生我的两个实体以及我遇到问题的地方如下

use Doctrine\ORM\Mapping as ORM;

/**
 * ProviderRate
 *
 * @ORM\Table(name="provider_rate", indexes={@ORM\Index(name="fk_proveedor_has_producto_compra_producto_compra1_idx", columns={"product_id"}), @ORM\Index(name="fk_id_tarifa_proveedor_id_moneda1_idx", columns={"currency_id"}), @ORM\Index(name="IDX_3A645C45A53A8AA", columns={"provider_id"})})
 * @ORM\Entity(repositoryClass="IDavid\FrontendBundle\Entity\ProviderRateRepository")
 */
class ProviderRate
{
/**
 * @var string
 *
 * @ORM\Column(name="reference", type="string", length=45, nullable=false)
 */
private $reference;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=45, nullable=false)
 */
private $name;

/**
 * @var string
 *
 * @ORM\Column(name="description", type="string", length=255, nullable=false)
 */
private $description;

/**
 * @var integer
 *
 * @ORM\Column(name="amount_per_unit", type="integer", nullable=true)
 */
private $amountPerUnit;

/**
 * @var string
 *
 * @ORM\Column(name="unit_price", type="decimal", precision=25, scale=3, nullable=false)
 */
private $unitPrice;

/**
 * @var string
 *
 * @ORM\Column(name="discount", type="decimal", precision=25, scale=3, nullable=false)
 */
private $discount;

/**
 * @var \IDavid\FrontendBundle\Entity\Providers
 *
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="NONE")
 * @ORM\OneToOne(targetEntity="IDavid\FrontendBundle\Entity\Providers")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="provider_id", referencedColumnName="id")
 * })
 */
private $provider;

/**
 * @var \IDavid\FrontendBundle\Entity\Products
 *
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="NONE")
 * @ORM\OneToOne(targetEntity="IDavid\FrontendBundle\Entity\Products")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 * })
 */
private $product;

/**
 * @var \IDavid\FrontendBundle\Entity\Currencies
 *
 * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Currencies")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
 * })
 */
private $currency;

use Doctrine\ORM\Mapping as ORM;

/**
 * Products
 *
 * @ORM\Table(name="products", uniqueConstraints={@ORM\UniqueConstraint(name="id_producto_UNIQUE", columns={"id"})}, indexes={@ORM\Index(name="fk_id_productos_id_categorias1_idx", columns={"category_id"}), @ORM\Index(name="fk_id_productos_id_producto_tipo1_idx", columns={"type"}), @ORM\Index(name="fk_id_productos_id_moneda1_idx", columns={"currency_id"})})
 * @ORM\Entity(repositoryClass="IDavid\FrontendBundle\Entity\ProductsRepository")
 */
class Products
{
    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=45, nullable=false)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string", length=255, nullable=false)
     */
    private $description;

    /**
     * @var string
     *
     * @ORM\Column(name="code", type="string", length=45, nullable=false)
     */
    private $code;

    /**
     * @var string
     *
     * @ORM\Column(name="description_long", type="text", nullable=false)
     */
    private $descriptionLong;

    /**
     * @var integer
     *
     * @ORM\Column(name="amount_per_unit", type="integer", nullable=false)
     */
    private $amountPerUnit;

    /**
     * @var string
     *
     * @ORM\Column(name="weight", type="decimal", precision=11, scale=3, nullable=false)
     */
    private $weight;

    /**
     * @var string
     *
     * @ORM\Column(name="web", type="string", length=100, nullable=false)
     */
    private $web;

    /**
     * @var boolean
     *
     * @ORM\Column(name="isActive", type="boolean", nullable=false)
     */
    private $isactive;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdtime", type="datetime", nullable=false)
     */
    private $createdtime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="modifiedtime", type="datetime", nullable=false)
     */
    private $modifiedtime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="deletedtime", type="datetime", nullable=true)
     */
    private $deletedtime;

    /**
     * @var boolean
     *
     * @ORM\Column(name="isDeleted", type="boolean", nullable=false)
     */
    private $isdeleted;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \IDavid\FrontendBundle\Entity\Categories
     *
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Categories")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     * })
     */
    private $category;

    /**
     * @var \IDavid\FrontendBundle\Entity\ProductTypes
     *
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\ProductTypes")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="type", referencedColumnName="id")
     * })
     */
    private $type;

    /**
     * @var \IDavid\FrontendBundle\Entity\Currencies
     *
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Currencies")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
     * })
     */
    private $currency;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Sets", inversedBy="product")
     * @ORM\JoinTable(name="products_sets",
     *   joinColumns={
     *     @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="set_id", referencedColumnName="id")
     *   }
     * )
     */
    private $set;

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Products", mappedBy="productParentid")
 */
private $product;

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Documents", inversedBy="product")
 * @ORM\JoinTable(name="product_attachments",
 *   joinColumns={
 *     @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="document_id", referencedColumnName="id")
 *   }
 * )
 */
private $document;

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Images", inversedBy="product")
 * @ORM\JoinTable(name="products_images",
 *   joinColumns={
 *     @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="image_id", referencedColumnName="id")
 *   }
 * )
 */
private $image;

 /**
     * Constructor
     */
    public function __construct()
    {
        $this->set = new \Doctrine\Common\Collections\ArrayCollection();
        $this->product = new \Doctrine\Common\Collections\ArrayCollection();
        $this->document = new \Doctrine\Common\Collections\ArrayCollection();
        $this->image = new \Doctrine\Common\Collections\ArrayCollection();
        $this->providerRate = new \Doctrine\Common\Collections\ArrayCollection();
    }

我尝试创建一个新变量以将两个表以相反的顺序加入到产品类中

/**
 * @ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", inversedBy="product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="id", referencedColumnName="product_id")
 * })
 */
private $providerRate;

但是当我进行 DQL 查询时,symfony 告诉我没有关联。 有没有办法做到这一点?

$dql = "SELECT p, pr FROM IDFrontendBundle:Products p
                        JOIN p.providerRate pr";
$query = $this->getEntityManager()->createQuery($dql);

【问题讨论】:

    标签: php symfony doctrine-orm dql


    【解决方案1】:

    双方的关系基数不同。

    ProviderRate -> Product (OneToOne)
    Product -> ProviderRate (OneToMany)
    

    因此,它不会起作用。 OneToOne应该在两边OneToMany应该和ManyToOne配对。

    我假设如下:

    • 一个Product 可以有多个ProviderRates。 对吗?

    如果是这样,您需要:

    ProviderRate 类

    /**
     * @var \IDavid\FrontendBundle\Entity\Products
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Products", mappedBy="providerRate")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     * })
     */
    private $product;
    

    产品类

    /**
     * @ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", inversedBy="product")
     */
    private $providerRate;
    

    如您所见,一旦在关系的任一侧声明@JoinColums,就无需在另一侧指定一个。此外,inversedBy 应与 mappedBy 匹配。

    这有帮助吗?

    编辑

    更改 mappedBy 和 inversedBy 属性顺序。

    ProviderRate 类

    /**
     * @var \IDavid\FrontendBundle\Entity\Products
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Products", inversedBy="providerRate")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     * })
     */
    private $product;
    

    产品类

    /**
     * @ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", mappedBy="product")
     */
    private $providerRate;
    

    【讨论】:

    • 您好 Jovan,感谢您的回答。我试过你提到我的东西,但仍然给我同样的错误。这是返回给我的错误消息。 Semantical Error] line 0, col 73 near 'pr': Error: Class IDavid\FrontendBundle\Entity\Products has no association named providerRate
    • 我尝试重启服务器,但还是不行。 Symfony 中是否有实体充值或清理任何类型的缓存?
    • 是的,重启服务器将是最后的手段,它应该清除服务器端缓存。你能用你尝试运行的查询来更新你的问题吗?
    • 我尝试运行的查询是:$dql = "SELECT p, pr FROM IDFrontendBundle:Products p JOIN p.providerRate pr"; $query = $this->getEntityManager()->createQuery($dql);
    • @JovanPerovic 小评论,用“cardinality”代替“carnality”;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 2011-02-07
    • 2015-09-22
    • 2018-08-08
    相关资源
    最近更新 更多