Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SF][Doctrine2] subquery i niepoprawne wypelnianie Encji
Forum PHP.pl > Forum > PHP > Frameworki
marcio
Mam pewien problem.
Posiadam w encje Gallery i GalleryImage:

Gallery:
  1. /**
  2.  * Meritoo\Cmf\GalleryBundle\Entity\Gallery
  3.  *
  4.  * @ORM\Table(name="cmf_gallery")
  5.  * @ORM\Entity(repositoryClass="Meritoo\Cmf\GalleryBundle\Repository\GalleryRepository")
  6.  */
  7. class Gallery implements Translatable {
  8.  
  9. /**
  10.   * @var integer $id
  11.   *
  12.   * @ORM\Column(name="id", type="integer")
  13.   * @ORM\Id
  14.   * @ORM\GeneratedValue(strategy="AUTO")
  15.   */
  16. private $id;
  17.  
  18. /**
  19.   * @var string $title
  20.   *
  21.   * @ORM\Column(name="title", type="string", length="100")
  22.   * @Gedmo\Translatable
  23.   */
  24. private $title;
  25.  
  26. /**
  27.   * @var string $title_slug
  28.   *
  29.   * @ORM\Column(name="title_slug", type="string", length="100")
  30.   * @Gedmo\Slug(fields={"title"})
  31.   * @Gedmo\Translatable
  32.   */
  33. private $title_slug;
  34.  
  35. /**
  36.   * @var text $description
  37.   *
  38.   * @ORM\Column(name="description", type="text", nullable="true")
  39.   * @Gedmo\Translatable
  40.   */
  41. private $description;
  42.  
  43. /**
  44.   *
  45.   * @var integer $position
  46.   *
  47.   * @ORM\Column(name="position", type="smallint", nullable="true")
  48.   */
  49. private $position;
  50.  
  51. /**
  52.   * @var datetime $created_at
  53.   *
  54.   * @ORM\Column(name="created_at", type="datetime")
  55.   * @Gedmo\Timestampable(on="create")
  56.   */
  57. private $created_at;
  58.  
  59. /**
  60.   * @var datetime $updated_at
  61.   *
  62.   * @ORM\Column(name="updated_at", type="datetime", nullable="true")
  63.   * @Gedmo\Timestampable(on="update")
  64.   */
  65. private $updated_at;
  66.  
  67. /**
  68.   * @var datetime $deleted_at
  69.   *
  70.   * @ORM\Column(name="deleted_at", type="datetime", nullable="true")
  71.   */
  72. private $deleted_at;
  73.  
  74. /**
  75.   * @ORM\OneToMany(targetEntity="GalleryImage", mappedBy="gallery")
  76.   */
  77. private $images;
  78.  
  79. /**
  80.   * The department, branch of the company / institution
  81.   *
  82.   * @ORM\ManyToOne(targetEntity="Meritoo\Cmf\DepartmentBundle\Entity\Department", inversedBy="galleries")
  83.   * @ORM\JoinColumn(name="department_id", referencedColumnName="id")
  84.   *
  85.   * @var \Meritoo\Cmf\DepartmentBundle\Entity\Department
  86.   */
  87. private $department;
  88.  
  89. /**
  90.   * The locale value (language code), e.g. pl_PL.
  91.   * This is not a mapped field of entity metadata, just a simple property.
  92.   *
  93.   * @var string
  94.   * @Gedmo\Locale
  95.   */
  96. private $locale;

GalleryImage:
  1. /**
  2.  * Meritoo\Cmf\GalleryBundle\Entity\GalleryImage
  3.  *
  4.  * @ORM\Table(name="cmf_gallery_images")
  5.  * @ORM\Entity(repositoryClass="Meritoo\Cmf\GalleryBundle\Repository\GalleryImageRepository")
  6.  * @ORM\HasLifecycleCallbacks
  7.  */
  8. class GalleryImage implements Translatable {
  9.  
  10. /**
  11.   * @var integer $id
  12.   *
  13.   * @ORM\Column(name="id", type="integer")
  14.   * @ORM\Id
  15.   * @ORM\GeneratedValue(strategy="AUTO")
  16.   */
  17. private $id;
  18.  
  19. /**
  20.   * @var string $title
  21.   *
  22.   * @Gedmo\Translatable
  23.   * @ORM\Column(name="title", type="string", length="50")
  24.   */
  25. private $title;
  26.  
  27. /**
  28.   * @var string $file_name
  29.   *
  30.   * @ORM\Column(name="file_name", type="string", length="100")
  31.   */
  32. private $file_name;
  33.  
  34. /**
  35.   *
  36.   * @var integer $position
  37.   *
  38.   * @ORM\Column(name="position", type="smallint", nullable="true")
  39.   */
  40. private $position;
  41.  
  42. /**
  43.   * @var boolean $is_main
  44.   *
  45.   * @ORM\Column(name="is_main", type="boolean")
  46.   */
  47. private $is_main = false;
  48.  
  49. /**
  50.   * @var datetime $created_at
  51.   *
  52.   * @ORM\Column(name="created_at", type="datetime")
  53.   * @Gedmo\Timestampable(on="create")
  54.   */
  55. private $created_at;
  56.  
  57. /**
  58.   * @var datetime $updated_at
  59.   *
  60.   * @ORM\Column(name="updated_at", type="datetime", nullable="true")
  61.   * @Gedmo\Timestampable(on="update")
  62.   */
  63. private $updated_at;
  64.  
  65. /**
  66.   * @var datetime $deleted_at
  67.   *
  68.   * @ORM\Column(name="deleted_at", type="datetime", nullable="true")
  69.   */
  70. private $deleted_at;
  71.  
  72. /**
  73.   * @ORM\ManyToOne(targetEntity="Gallery", inversedBy="images")
  74.   * @ORM\JoinColumn(name="gallery_id", referencedColumnName="id")
  75.   *
  76.   * @var \Meritoo\Cmf\GalleryBundle\Entity\Gallery
  77.   */
  78. private $gallery;
  79.  
  80. /**
  81.   * @Assert\File(maxSize="6000000")
  82.   * @var \Symfony\Component\HttpFoundation\File\UploadedFile
  83.   */
  84. private $file;
  85.  
  86. /**
  87.   * Helper for uploading.
  88.   * Used for upload operations etc.
  89.   *
  90.   * @var \Meritoo\Cmf\CommonBundle\Helper\UploadHelper
  91.   */
  92. private $uploadHelper;
  93.  
  94. /**
  95.   * The locale value (language code), e.g. pl_PL.
  96.   * This is not a mapped field of entity metadata, just a simple property.
  97.   *
  98.   * @var string
  99.   * @Gedmo\Locale
  100.   */
  101. private $locale;
  102.  

Musze pobrac za pomoja 1 zapytania wszystkie galerie ktore posiadaja przynajmniej 1 zdjecie, czyli pomijamy wszystkie puste galerie.
Mam metode w repository:
  1. /**
  2.   * Returns all galleries
  3.   *
  4.   * @param [integer $limit = 0] Maximum amount of items
  5.   * @param [integer $offset = 0] The start position, offset
  6.   * @param [boolean $skipEmpty = false] if is set to true galleries without images are skipped. Otherwise not.
  7.   * @return array
  8.   */
  9. public function getGalleries($limit = 0, $offset = 0, $skipEmpty = false) {
  10. if (!$skipEmpty) {
  11. $orderBy = array(
  12. 'position' => 'ASC',
  13. 'created_at' => 'DESC'
  14. );
  15.  
  16. $criteria = $this->getCriteriaParameters();
  17. $galleries = $this->getResult($criteria, $orderBy, $limit, $offset);
  18. } else {
  19. $skipEmptyGalleriesSubQuery = $this->createQueryBuilder('g')
  20. ->select('g.id')
  21. ->leftJoin('g.images', 'i', \Doctrine\ORM\Query\Expr\Join::WITH, 'i.deleted_at is null')
  22. ->where('g.deleted_at is null')
  23. ->andWhere('i.id is not null')
  24. ->groupBy('g.id')
  25. ->getDQL();
  26.  
  27. $queryBuilder = $this->createQueryBuilder('c');
  28. $queryBuilder->where($queryBuilder->expr()->in('c.id', $skipEmptyGalleriesSubQuery))
  29. ->orderBy('c.position', 'ASC')
  30. ->addOrderBy('c.created_at', 'DESC');
  31.  
  32. if ($limit > 0) {
  33. $queryBuilder->setMaxResults($limit);
  34. }
  35.  
  36. if ($offset > 0) {
  37. $queryBuilder->setFirstResult($offset);
  38. }
  39.  
  40. $galleries = $queryBuilder->getQuery()->getResult();
  41. }
  42. return $galleries;
  43. }

W czym problem.
Mianowicie, zapytanie subquery wyglada dobrze zwraca mi id galeri ktore maja przynajmniej 1 zdjecie.
Glowne zapytanie zwraca mi kolumny(obiekt Gallery) dla nie pustych galerii sprawdzalem w phpmyadmin.
Jednak w "kodzie" zwraca obiekty ale z pustymi wlasciwosciami.
Jedyna metoda z Encji ktora nie zwraca pustej wartosci to:
  1. //przyklad opiera sie o foreach() dla wartosci ktora zwraca getGalleries()
  2. print $entity->getId(); //ok
  3. print $entity->getTitle(); //i tu juz jest pusto mamy pusty string

I tak samo jesli chodzi o wszystkie inne pola.

Czy ktos wie gdzie moze byc problem?

Tak wyglada wygenerowane zapytanie:
  1. SELECT c0_.id AS id0, c0_.title AS title1, c0_.title_slug AS title_slug2, c0_.description AS description3, c0_.position AS position4, c0_.created_at AS created_at5, c0_.updated_at AS updated_at6, c0_.deleted_at AS deleted_at7, c0_.department_id AS department_id8
  2. FROM cmf_gallery c0_
  3. WHERE c0_.id
  4. IN (
  5.  
  6. SELECT c1_.id
  7. FROM cmf_gallery c1_
  8. LEFT JOIN cmf_gallery_images c2_ ON c1_.id = c2_.gallery_id
  9. AND (
  10. c2_.deleted_at IS NULL
  11. )
  12. WHERE c1_.deleted_at IS NULL
  13. AND c2_.id IS NOT NULL
  14. GROUP BY c1_.id
  15. )
  16. ORDER BY c0_.position ASC , c0_.created_at DESC
  17. LIMIT 3
BugsBunny
Spróbuj z modelu usunąć dla pola title @Gedmo\Translatable. Według mnie w tym tkwi problem.

Jak nie pomoże to sprawdź jeszcze czy usuwając transable dla pola description też będzie puste. Być może Doctrine nie radzi sobie z zapytaniem i miesza obiekty czyli title wsadziło Ci z GalleryImage, ale to raczej mało prawdopodobne.
marcio
Ok sprawdze juz jutro rano.
Choc te adnotacje sa potrzebne.

Chce tylko przypomniec ze w ogole nie ustawil wartosci oprocz id, podam kawalek var_dump-a:
Kod
object(Meritoo\Cmf\GalleryBundle\Entity\Gallery)#1296 (11) { ["id":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> int(10) ["title":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> string(0) "" ["title_slug":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> string(0) "" ["description":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> string(0) "" ["position":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> NULL ["created_at":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> object(DateTime)#1230 (3) { ["date"]=> string(19) "2012-09-20 09:48:54" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" } ["updated_at":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> object(DateTime)#1300 (3) { ["date"]=> string(19) "2012-09-20 09:48:54" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/Berlin" } ["deleted_at":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> NULL ["images":"Meritoo\Cmf\GalleryBundle\Entity\Gallery":private]=> object(Doctrine\ORM\PersistentCollection)#1289 (9) { ["snapshot":"Doctrine\ORM\PersistentCollection":private]=> array(0) { } ["owner":"Doctrine\ORM\PersistentCollection":private]=> *RECURSION* ["association":"Doctrine\ORM\PersistentCollection":private]=> array(15) { ["fieldName"]=> string(6) "images" ["mappedBy"]=> string(7) "gallery" ["targetEntity"]=> string(45) "Meritoo\Cmf\GalleryBundle\Entity\GalleryImage" ["cascade"]=> array(0) { }


Jak widac wszystko jest ok tylko title,title_slug i description nie.
Wiec zapewne chodzi o @Gedmo\Transatable, to musi byc.
Zobacze dokladnie inne repozytoria/helpery systemu zeby naprawic ten problem.

Ewentualnie jak to mozna poprawic utrzymujac przy tym @Gedmo\Translatable

Cytat(BugsBunny @ 20.09.2012, 23:22:31 ) *
Spróbuj z modelu usunąć dla pola title @Gedmo\Translatable. Według mnie w tym tkwi problem.

Jak nie pomoże to sprawdź jeszcze czy usuwając transable dla pola description też będzie puste. Być może Doctrine nie radzi sobie z zapytaniem i miesza obiekty czyli title wsadziło Ci z GalleryImage, ale to raczej mało prawdopodobne.

Rozwiazalem to metoda setHints(), twoja odp. naprowadzila mnie na rozwiazanie wink.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.