Pomm Bundle与spl_object_hash相同但对象不同

时间:2017-08-31 15:35:57

标签: symfony pomm

我在我的symfony项目中使用Pomm包,我遇到了问题 我创建了一个复杂的查询和我的结果实例相同的对象具有不同的属性。 这只是举例,但这个请求有一个关系 - >很多

我知道这个请求(1 - >很多)从关系角度来看是不正确的但是我想了解pomm bundle我是如何生成两次相同的对象引用

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);
}

并且var_dump结果:



         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"

3 个答案:

答案 0 :(得分:0)

只要中间件提供了面向对象的数据库行表示,它就必须处理一个问题:如果从两个不同的查询中获取两次行,该怎么办? Pomm使用identity mapper来跟踪所获取的对象。

身份映射器使用实体的主键来识别行,每次从迭代器中获取行时,如果它已经存在于实体映射器中,则实体将使用新值进行丰富并返回。这意味着获取的行保存在内存中,如果读取了大量记录,则可能会出现问题。

答案 1 :(得分:0)

好的,谢谢你的回答。

在我的SF项目中,我必须使用现有的postgresql数据库(否​​则我将使用Doctrine来管理我的数据库)

没有想到基地"对象"也不是" web"我有时不得不提出要求让我对物体碰撞产生这种担忧。

然而,我通过创建"观点"找到了一个技巧。返回与我的映射实体完全相同的行,但是使用新的" ID"根据我的观点自动增加。

这不是最干净的方法,但在我的情况下它完美无缺。

答案 2 :(得分:0)

让我们举一个碰撞的例子:

仅当我在单个数组中合并两个对象数组时才会发生冲突。 独立$ listing_value和$ listing_value2即使它具有相同的对象,也不会产生冲突。

检查示例:

   $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;
}

转储1:

    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)
}

转储2:

    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)
}