0

I use Pomm bundle for my symfony Project and i have a problem I have create a complex query and my result instance same object with different attributes. It's just for example but this request have relation one -> many

I know that this request (1 -> many) is not correct from a relational point of view however I would like to understand how pomm bundle me generates twice the same object reference

public function getSousFamilleParametreListing(Where $condition = null,$locale='fr')
{

$sql ="
select
    {projection}
from
    {sousfamilleparametre} sfp
    inner join {parametre} par ON sfp.\"Parametre\" = par.\"ID\"
    inner join {parametre_valeur} pav ON pav.\"Parametre\" = sfp.\"Parametre\"
    inner join {valeur} val ON pav.\"Valeur\" = val.\"ID\"

where {condition}
    order by sfp.\"Niveau\", sfp.\"Pos\", pav.\"Pos\""
    ;

 $projection = $this->createProjection()
                    ->setField('nom_param','par."Nom"','text')
                    ->setField('type_param','par."Type"','text')
                    ->setField('pos_valeur', 'pav."Pos"','text')
                    ->setField('Valeur', 'val."ID"','text')
                    ->setField('nom_valeur','val."Nom"','text')
                    ->setField('couleur_valeur','val."ValCouleur"','text')
                    ->setField('sur_mesure','val."SurMesure"','boolean');


$parametre = $this->getSession()
                  ->getModel(ParametreModel::class);

$valeur = $this->getSession()
               ->getModel(ValeurModel::class);

$parametre_valeur = $this->getSession()
                         ->getModel(ParametrevaleurModel::class);

$condition = (new Where)->andWhere($condition);


$sql = strtr(
    $sql,
    [
        '{projection}'          => $projection->formatFieldsWithFieldAlias('sfp'),
        '{sousfamilleparametre}'=> $this->structure->getRelation(),
        '{parametre}'           => $parametre->getStructure()->getRelation(),
        '{valeur}'              => $valeur->getStructure()->getRelation(),
        '{parametre_valeur}'    => $parametre_valeur->getStructure()->getRelation(),
        '{locale}'              => $locale,
        '{condition}'           => $condition,
    ]
);

return $this->query($sql,$condition->getValues(),$projection);
}

And var_dump result :



         object(AppBundle\Entity\Model\MyDb1\PublicSchema\Sousfamilleparametre)#574 (2) {
      ["container":protected]=>
      array(11) {
        ["SousFamille"]=>
        int(8)
        ["Parametre"]=>
        int(375)
        ["Pos"]=>
        int(0)
        ["Niveau"]=>
        int(1)
        ["nom_param"]=>
        string(6) "TAILLE"
        ["type_param"]=>
        string(1) "6"
        ["pos_valeur"]=>
        string(1) "0"
        ["Valeur"]=>
        string(1) "7"
        ["nom_valeur"]=>
        string(2) "T1"
        ["couleur_valeur"]=>
        string(7) "#4F4FFF"
        ["sur_mesure"]=>
        bool(false)
      }
      ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
      int(1)
    }
    string(32) "0000000067acae310000000004f8d20f"
    object(AppBundle\Entity\Model\MyDb1\PublicSchema\Sousfamilleparametre)#574 (2) {
      ["container":protected]=>
      array(11) {
        ["SousFamille"]=>
        int(8)
        ["Parametre"]=>
        int(375)
        ["Pos"]=>
        int(0)
        ["Niveau"]=>
        int(1)
        ["nom_param"]=>
        string(6) "TAILLE"
        ["type_param"]=>
        string(1) "6"
        ["pos_valeur"]=>
        string(1) "1"
        ["Valeur"]=>
        string(1) "8"
        ["nom_valeur"]=>
        string(2) "T2"
        ["couleur_valeur"]=>
        string(7) "#2424FF"
        ["sur_mesure"]=>
        bool(false)
      }
      ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
      int(1)
    }
    string(32) "0000000067acae310000000004f8d20f"

Jason Roman
  • 8,146
  • 10
  • 35
  • 40

3 Answers3

0

As soon as a middleware provides an object oriented representation of a database rows, it must deal with a problem: what to do if a row is fetched twice even from two different queries? Pomm uses an identity mapper to keep track of the fetched objects.

The identity mapper uses entity’s primary key to recognize a row, every time a row is fetched from an iterator, if it is already present in the entity mapper, the entity is enriched with the new values and returned. This means fetched rows are kept in memory which can be a problem if a lot of records are read.

greg
  • 3,354
  • 1
  • 24
  • 35
0

OK thanks for your answer.

In my SF project I have to work with an existing postgresql database (otherwise I will have used Doctrine to manage my database)

The base is not thought "object" nor "web" I am sometimes obliged to make requests bringing me to have this concern of object collision.

However, I found a trick by creating "views" that return exactly the same lines as my mapped entity but with a new "ID" auto increment based on my view.

This is not the cleanest method but in my case it works perfectly.

0

Let's take an example of a collision:

The collision occurs only when I merge the two arrays of objects in a single array. Independament $ listing_value and $ listing_value2 even if it has the same objects this does not create collision.

Check the example :

   $listing_valeur =  $this->get('pomm')
                              ->getDefaultSession()
                              ->getModel(ParametrevaleurModel::class)
                              ->getParametreValeur(new Where("pav.\"Parametre\" in ($custom)",$tab_id),
                                                    "position(pav.\"Parametre\"::text in '".join(',',$tab_id)."')",
                                                    $request->getLocale());


    $listing_valeur2 =  $this->get('pomm')
                              ->getDefaultSession()
                              ->getModel(ParametrevaleurModel::class)
                              ->getParametreValeur(new Where("pav.\"Parametre\" in ($custom)",$tab_id),
                                                    "position(pav.\"Parametre\"::text in '".join(',',$tab_id)."')",
                                                    $request->getLocale());
                              $tab=array();

foreach ($listing_valeur as $key => $value) {
//DUMP1
   echo "<pre>";
        var_dump($value);
    echo "</pre>";
    $tab[] = $value;
}

foreach ($listing_valeur2 as $key1 => $value1) {
    $value1->set('Pos',10);
    //DUMP2
    echo "<pre>";
        var_dump($value1);
    echo "</pre>";
    //$value & $value1 same spl_object_hash bug value different on POS
    $tab[] = $value1;
}
echo "<hr>";
 foreach ($tab as $key => $value) {
    //WHEN ITERATE TAB COLLISION OBJET POS = 10 on VALUE & VALUE1
   echo "<pre>";
        var_dump($value);
    echo "</pre>";
}

echo "dump1A<br/>";
foreach ($listing_valeur as $key => $value) {
//DUMP1A
   echo "<pre>";
        var_dump($value);
    echo "</pre>";
    $tab[] = $value;
}

Dump1 :

    object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
  ["container":protected]=>
  array(6) {
    ["Parametre"]=>
    int(375)
    ["Valeur"]=>
    int(7)
    ["Pos"]=>
    int(0)
    ["nom_valeur"]=>
    string(2) "T1"
    ["couleur_valeur"]=>
    string(7) "#4F4FFF"
    ["sur_mesure"]=>
    bool(false)
  }
  ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
  int(1)
}

Dump2 :

    object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
  ["container":protected]=>
  array(6) {
    ["Parametre"]=>
    int(375)
    ["Valeur"]=>
    int(7)
    ["Pos"]=>
    int(10)
    ["nom_valeur"]=>
    string(2) "T1"
    ["couleur_valeur"]=>
    string(7) "#4F4FFF"
    ["sur_mesure"]=>
    bool(false)
  }
  ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
  int(3)
}

dump3 (tab iterate)

    object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
  ["container":protected]=>
  array(6) {
    ["Parametre"]=>
    int(375)
    ["Valeur"]=>
    int(7)
    ["Pos"]=>
    int(10)
    ["nom_valeur"]=>
    string(2) "T1"
    ["couleur_valeur"]=>
    string(7) "#4F4FFF"
    ["sur_mesure"]=>
    bool(false)
  }
  ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
  int(3)
}
object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
  ["container":protected]=>
  array(6) {
    ["Parametre"]=>
    int(375)
    ["Valeur"]=>
    int(7)
    ["Pos"]=>
    int(10)
    ["nom_valeur"]=>
    string(2) "T1"
    ["couleur_valeur"]=>
    string(7) "#4F4FFF"
    ["sur_mesure"]=>
    bool(false)
  }
  ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
  int(3)
}

Dump1A :

object(AppBundle\Entity\Model\MyDb1\PublicSchema\Parametrevaleur)#591 (2) {
  ["container":protected]=>
  array(6) {
    ["Parametre"]=>
    int(375)
    ["Valeur"]=>
    int(7)
    ["Pos"]=>
    int(0)
    ["nom_valeur"]=>
    string(2) "T1"
    ["couleur_valeur"]=>
    string(7) "#4F4FFF"
    ["sur_mesure"]=>
    bool(false)
  }
  ["status":"PommProject\ModelManager\Model\FlexibleEntity\FlexibleContainer":private]=>
  int(3)
}