Doctrine2一对多/多对一的关系给出重复的记录

问题描述:

我有三个表 1)产品类别(一个类别可以有很多产品) 2)产品(一个产品应该属于一个类别,可以有0或多个图像) 3)产品图片(一个图像应该属于一个产品)Doctrine2一对多/多对一的关系给出重复的记录

现在我想从偏移0 施加8的限制的产品有6种产品在我的数据库。 我想要的是每个产品都有类别和图像的细节。为此我使用了doctrine 2关联映射。

我的实体如下: -

<?php 

    namespace Nitin\TestBundle\Entity; 

    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * Nitin\TestBundle\Entity\Product 
    * 
    * @ORM\Table(name="product", indexes={@ORM\Index(name="fk_product_cat", columns={"fk_product_cat"})}) 
    * @ORM\Entity(repositoryClass="Nitin\TestBundle\Repository\ProductRepository") 
    */ 
    class Product 
    { 
     /** 
     * @var integer 
     * 
     * @ORM\Column(name="id", type="integer", nullable=false) 
     * @ORM\Id 
     * @ORM\GeneratedValue(strategy="IDENTITY") 
     */ 
     private $id; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="product_title", type="string", length=250, nullable=false) 
     * @Assert\NotBlank(message = "Please enter valid product title.") 
     */ 
     private $productTitle; 

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

     /** 
     * @var float 
     * 
     * @ORM\Column(name="price", type="float", precision=10, scale=0, nullable=false) 
     * @Assert\NotBlank 
     * Assert\Type(type="float", message="The value should have decimal points.") 
     */ 
     private $price; 

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

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

     /** 
     * @var boolean 
     * 
     * @ORM\Column(name="featured", type="boolean", precision=0, scale=0, nullable=false, unique=false) 
     */ 
     private $featured; 

     /** 
     * @var \Nitin\TestBundle\Entity\ProductCategory 
     * 
     * @ORM\ManyToOne(targetEntity="Nitin\TestBundle\Entity\ProductCategory", cascade={"persist", "remove"}) 
     * @ORM\JoinColumns({ 
     * @ORM\JoinColumn(name="fk_product_cat", referencedColumnName="id", onDelete="CASCADE") 
     * }) 
     * @Assert\NotBlank(message = "Please Select Product Category.") 
     */ 
     private $fkProductCat; 

     /** 
     * @var \Doctrine\Common\Collections\Collection 
     * 
     * @ORM\OneToMany(targetEntity="Nitin\TestBundle\Entity\ProductImages", mappedBy="fkProduct", cascade={"persist"}) 
     * 
     */ 
     private $images; 

代码产品类别实体是: -

<?php 

    namespace Nitin\TestBundle\Entity; 

    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * Nitin\TestBundle\Entity\ProductCategory 
    * 
    * @ORM\Table(name="product_category", indexes={@ORM\Index(name="fk_parent", columns={"fk_parent"})}) 
    * @ORM\Entity(repositoryClass="Nitin\TestBundle\Repository\ProductCategoryRepository") 
    */ 
    class ProductCategory 
    { 
     /** 
     * @var integer 
     * 
     * @ORM\Column(name="id", type="integer", nullable=false) 
     * @ORM\Id 
     * @ORM\GeneratedValue(strategy="IDENTITY") 
     */ 
     private $id; 

     /** 
     * @var string 
     * 
     * @ORM\Column(name="category_name", type="string", length=250, nullable=false) 
     * @Assert\NotBlank 
     */ 
     private $categoryName; 

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

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

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

     /** 
     * @var \Nitin\TestBundle\Entity\ProductCategory 
     * 
     * @ORM\ManyToOne(targetEntity="Nitin\TestBundle\Entity\ProductCategory", cascade={"persist", "remove"}) 
     * @ORM\JoinColumns({ 
     * @ORM\JoinColumn(name="fk_parent", referencedColumnName="id", onDelete="CASCADE") 
     * }) 
     */ 
     private $fkParent; 

     /** 
     * @var \Doctrine\Common\Collections\Collection 
     * 
     * @ORM\OneToMany(targetEntity="Nitin\TestBundle\Entity\ProductCategory", mappedBy="fkParent", cascade={"persist"}) 
     */ 
     private $child; 

代码产品图片实体是

<?php 

    namespace Nitin\TestBundle\Entity; 

    use Doctrine\ORM\Mapping as ORM; 
    use Symfony\Component\HttpFoundation\File\UploadedFile; 
    use Symfony\Component\Validator\Constraints as Assert; 

    /** 
    * ProductImages 
    * 
    * @ORM\Table(name="product_images", indexes={@ORM\Index(name="fk_product", columns={"fk_product"})}) 
    * @ORM\Entity 
    * @ORM\HasLifecycleCallbacks 
    */ 
    class ProductImages { 

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

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

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

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

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

     /** 
     * @var \Nitin\TestBundle\Entity\Product 
     * 
     * @ORM\ManyToOne(targetEntity="Nitin\TestBundle\Entity\Product", inversedBy="id", cascade={"merge", "remove"}) 
     * @ORM\JoinColumns({ 
     * @ORM\JoinColumn(name="fk_product", referencedColumnName="id", onDelete="CASCADE") 
     * }) 
     */ 
     private $fkProduct; 

     /** 
     * @Assert\File(maxSize="6000000") 
     */ 
     private $file; 

为了获得结果,我通过存储库中的自定义函数使用Doctrine查询生成器: -

  <?php 

    namespace Nitin\TestBundle\Repository; 

    use Doctrine\ORM\EntityRepository; 

    /** 
    * ProductRepository 
    * 
    * This class was generated by the Doctrine ORM. Add your own custom 
    * repository methods below. 
    */ 
    class ProductRepository extends EntityRepository { 
    public function getAllProduct($offset = 0, $limit = 10, $arrayResult = true) { 
      $qb = $this->_em->createQueryBuilder(); 

      $qb->select(array('p', 'pc', 'img')) 
        ->from($this->_entityName, 'p') 
        ->leftJoin('p.fkProductCat', 'pc') 
        ->leftJoin('p.images', 'img') 
        //->add('where ', $qb->expr()->countDistinct('p.id')) 
        ; 


      //Pagination logic 
      $from = (int) $offset; 
      $start = ($from == 1) ? ($from - 1) : (($from - 1) * $limit); 
      $start = ($start < 0) ? 0 : $start; 
      $qb->setFirstResult($start); 
      $qb->setMaxResults($limit); 
      //echo $qb->getQuery()->getSQL();die; 
      if (TRUE === $arrayResult) { 
       return $qb->getQuery()->getArrayResult(); 
      } 
      return $qb->getQuery()->getResult(); 
     } 

,并呼吁在控制器这样的功能: -

<?php 

    namespace Nitin\TestBundle\Controller; 

    use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

    class IndexController extends Controller 
    { 
     private $data = array(); 

     public function indexAction() 
     { 
      $em = $this->getDoctrine()->getEntityManager(); 
      $this->data['latestProduct'] = $em->getRepository('BitcoinAdminBundle:Product')->getAllProduct(0, 8); 

      return $this->render('BitcoinSiteBundle:Default:index.html.twig', $this->data); 
     } 
    } 

我期待着6条,但只获得了3。当我尝试打印SQL和运行在我的分贝该查询,我发现查询返回重复记录。

所以,任何人都可以提出我犯了错误的地方。

感谢

尝试setMaxResults();之后加入return $paginator = new Paginator($qb->getQuery, $fetchJoinCollection = true);。加入收藏时,这是一个常见问题。