Symfony / Doctrine - Twig_Error_Runtime:Catchable致命错误:类Doctrine \ ORM \ PersistentCollection的对象无法转换为字符串

时间:2015-01-26 12:56:07

标签: symfony doctrine-orm many-to-many twig dql

我的symfony项目中有这个实体:

/**
 * Batiments
 *
 * @ORM\Table(name="batiments")
 * @ORM\Entity
 * @ORM\Entity(repositoryClass="MySpace\DatabaseBundle\Repository\BatimentsRepository")
 */
class Batiments
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

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

    /**
     * @ORM\ManyToOne(targetEntity="MySpace\DatabaseBundle\Entity\Ensembles")
     * @ORM\JoinColumn(nullable=false)
     */
    private $ensembles;

    /**
 * @ORM\ManyToMany(targetEntity="MySpace\DatabaseBundle\Entity\Typesactivite")
 * @ORM\JoinTable(name="batiments_typesactivite",
 *      joinColumns={@ORM\JoinColumn(name="batiments_id", referencedColumnName="id", nullable=false)},
 *      inverseJoinColumns={@ORM\JoinColumn(name="typesactivite_id", referencedColumnName="id", nullable=false)}
 *      )
 */
private $typesactivite;

//getters and setters

如您所见,ManyToOne$ensembles的关系ManyToMany$typesactivite的{​​{1}}关系。{/ p>

我有这个SQL请求:

SELECT b.referenceBatiment, b.nom, e.nom, p.nom, b.surfaceChauffee, ta.type
FROM `batiments` b, `ensembles` e, `parcsimmobilier` p, `typesactivite` ta, `batiments_typesactivite` bta
WHERE b.ensembles_id = e.id
AND e.parcsimmobilier_id = p.id
AND b.id = bta.batiments_id
AND ta.id = bta.typesactivite_id
GROUP BY p.nom, e.nom, b.nom, ta.type

PhpMyAdmin 上,SQL请求运行良好,因此我必须在Symfony项目中导入我的SQl请求(DQL with Doctrine)。

我在 controller.php

中尝试此操作
$query=$em->createQuery('SELECT b
                         FROM MySpaceDatabaseBundle:Ensembles e,  MySpaceDatabaseBundle:Typesactivite ta, MySpaceDatabaseBundle:Parcsimmobilier p, MySpaceDatabaseBundle:Batiments b
                         WHERE b.ensembles = e.id
                         AND b.typesactivite = ta.id');

它似乎有效,但仅适用于ManyToOne关系。我将结果显示在 html.twig 中的<table>标记中,如下所示:

<table id="dataTablesBatiments" class="table table-bordered table-hover" cellspacing="0" width="100%">
                <thead>
                  <tr>
                    <th>Référence</th>
                    <th>Parc</th>
                    <th>Nom</th>
                    <th>Ensemble</th>
                    <th>Type d'activité</th>
                    <th>Surface</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                  {% for batiments in batiment %}
                    <tr>
                      <td>{{ batiments.referencebatiment }}</td>
                      <td>{{ batiments.ensembles.parcsimmobilier }}</td>
                      <td>{{ batiments.nom }}</td>
                      <td>{{ batiments.ensembles }}</td>
                      <td>{{ batiments.typesactivite }}</td>
                      <td>{{ batiments.surfacechauffee }}</td>
                      <td><a href=""><button class="btn btn-warning btn-xs">Modifier</button></a></td>
                    </tr>
                  {% endfor %}
              </tbody>
            </table>

但我有这个错误:

  

[语义错误]第0行,第328行附近&#39; typesactivite&#39;:错误:   无效的PathExpression。 StateFieldPathExpression或   SingleValuedAssociationField预期。


最后更新


根据所有建议,我尝试根据学说参考文档和Symfonybook来做到这一点。删除查询请求后,我的控制器中的代码如下:

$em=$this->getDoctrine()->getManager();
        $batiment = $em->getRepository('MySpaceDatabaseBundle:Batiments')->findAll();

        return $this->render('MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig', array('batiment' => $batiment ));
}

但是现在发生了这个错误:

  

在渲染模板期间抛出了异常   (&#34; Catchable Fatal Error:类的对象   Doctrine \ ORM \ PersistentCollection无法转换为字符串   C:\瓦帕\ WWW ......... \应用\缓存\ dev的\树枝\ BF \ 66 \ 146a31a62bf6f2a549d2604fb5be9c4530ab760a10169af08e8a5b72e9ee.php   第127行&#34;)in   MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig at   第60行。

就像你可以看到的,在我的树枝上,一切都是正确的。有人?

感谢您的帮助。

7 个答案:

答案 0 :(得分:2)

似乎我找到了解决方案,感谢另一位开发人员(顺便说一句,再次感谢你)。

看看here:事实上你必须在你的树枝上做一个循环。

因为代码应该是这样的:

<tbody>
       {% for batiments in batiment %}
         <tr>
           <td>{{ batiments.referencebatiment }}</td>
           <td>{{ ... }}</td>
           <!-- your loop here -->
           <td>
             {% for batiments in batiments.typesactivite %}
               {{ batiments.type }}
             {% endfor %}
           </td>
        {% endfor %}
</tbody>

希望它可以帮助你。

答案 1 :(得分:1)

尝试这个(使用@Gregsparrow建议):

$qb = $this-> $em->getRepository("YourBundle:Batiments")
                        ->createQueryBuilder('b');

// @Gregsparrows suggestion queryBuilder
$qb ->select("b")
    ->from("Batiments", "b")
    ->leftJoin(...")
    ->leftJoin("...");

$batiment = $qb->getResult();

return $this->render('...') ;

匹配吗?

答案 2 :(得分:1)

错误

$batiment = $em->getRepository('MySpaceDatabaseBundle:Batiments');
$qb = $this->$em->createQueryBuilder(b);

$qb = $em->getRepository('MySpaceDatabaseBundle:Batiments')->createQueryBuilder('b');

答案 3 :(得分:1)

也许你应该这样:

$batiments = $this->createQueryBuilder('b')
->join('b.ensembles', 'e')
->join('b.typesactivites', 'ta')
->addSelect('e')
->addSelect('ta')
->where('b.ensembles = :ensembles')
->andWhere('b.typesactivite= :typesactivite');

请注意您使用条款,因此数据透视表 batiments_typesactivite在您的symfony项目中存在,请认为在 OOP和对象关系


UPADTE

这匹配:

   $batiments = $this->createQueryBuilder('b')
    ->join('b.ensembles', 'e')
    ->join('b.typesactivites', 'ta')
    ->addSelect('e')
    ->addSelect('ta')
    ->where('b.ensembles = :ensembles')
    ->andWhere('b.typesactivite= :typesactivite');

$batiment = $query->getResult();

答案 4 :(得分:1)

根据http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#many-to-many-unidirectionalhttp://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#many-to-many-bidirectional,您在两个实体之间需要的不是整数值,而是整个表。 如果我正确理解你的模型,“Batiment”可以有多个“Type d'activité”,反之亦然,因此你需要一个“BatimentTypeActivite”表。 结果表看起来像这样:

BATIMENT   ID   名称

Activte   ID   名称

BatimentActivite   id_batiment   id_activite

答案 5 :(得分:1)

您应该尝试使用获取连接来实现此代码:

    $queryBatiments = $em->createQuery('SELECT b, ta, e
                                    FROM MySpaceDatabaseBundle:Batiments b
                                    JOIN b.typesactivite ta
                                    JOIN b.ensembles e
                                    WHERE b.ensembles = e.id');

    $batiment = $queryBatiments->getResult();

    return $this->render ('MySpaceGestionPatrimoinesBundle:Batiments:indexBatiments.html.twig', array ('batiment' => $batiment ));
}

根据Doctine参考文档here中的加入参数,您可能必须使用FETCH JOIN继续执行 DQL 请求。

它是否符合您的问题?

答案 6 :(得分:0)

也许IDENTITY会帮助你...... IDENTITY(b.typesactivite)

修改

另类就是那种

假设$qb是您的查询构建器实例

$qb->select("b")->from("Batiments", "b")
   ->leftJoin("Ensemble", "e", \Doctrine\ORM\Query\Expr\Join::WITH, "b.ensembles = e.id")
   ->leftJoin("Typesactivite", "ta",  \Doctrine\ORM\Query\Expr\Join::WITH, "b.typesactivite = ta.id");