使用 JMS Serializer 时禁用 Doctrine 2 延迟加载?

我在我的 Zend 项目中使用 Doctrine 2 ORM,并且在某些情况下需要将我的实体序列化为 JSON.

Im using Doctrine 2 ORM in my Zend project and need to serialize my Entities to JSON in several cases.

ATM 我使用 Querybuilder 并加入我需要的所有表.但是我的序列化程序会导致教义延迟加载每个关联的实体,这会导致数据量非常大并引发递归.

ATM i use the Querybuilder and join all tables i need. But my serializer causes doctrine to lazy load every associated Entity which results in pretty huge data amounts and provokes recursion.

现在我正在寻找一种完全禁用 Doctrine 延迟加载行为的方法.

Now im looking for a way to totally disable Doctrines lazy loading behavior.

我选择数据的方式如下:

My way to select data would be the following:

$qb= $this->_em->createQueryBuilder()
            ->from("ProjectEntityPersonappointment", 'pa')
            ->select('pa', 't', 'c', 'a', 'aps', 'apt', 'p')
            ->leftjoin('pa.table', 't')
            ->leftjoin('pa.company', 'c')
            ->leftjoin('pa.appointment', 'a')
            ->leftjoin('a.appointmentstatus', 'aps')
            ->leftjoin('a.appointmenttype', 'apt')
            ->leftjoin('a.person','p')

我希望我的结果集只包含选定的表和关联.

I would like my resultset to only contain the selected tables and associations.

任何帮助将不胜感激.

推荐答案

在 Doctrine 中寻找答案后,我的团队发现 JMS Serializer 是问题".它自动触发了 Doctrine Proxies 的使用.我们为 JMS Serializer 编写了一个补丁来避免延迟加载.

After having looked for the answer in Doctrine, my team figured out that the JMS Serializer was the "problem". It triggered the use of Doctrine Proxies automatically. We wrote a Patch for JMS Serializer to avoid the Lazy Loading.

我们实现了自己的 DoctrineProxyHandler,它不会触发 Doctrine 延迟加载机制,并将其注册到我们的 SerializationHandlers 数组中.

We implemented our own DoctrineProxyHandler which just doesn't trigger Doctrines lazyloading mechanism and registered it within our SerializationHandlers Array.

class DoctrineProxyHandler implements SerializationHandlerInterface {

public function serialize(VisitorInterface $visitor, $data, $type, &$handled)
{
    if (($data instanceof Proxy || $data instanceof ORMProxy) && (!$data->__isInitialized__ || get_class($data) === $type)) {
        $handled = true;

        if (!$data->__isInitialized__) {

            //don't trigger doctrine lazy loading
            //$data->__load();

            return null;
        }

        $navigator = $visitor->getNavigator();
        $navigator->detachObject($data);

        // pass the parent class not to load the metadata for the proxy class
        return $navigator->accept($data, get_parent_class($data), $visitor);
    }

    return null;
}

现在我可以简单地选择我的表格,加入我需要的关联 - 我的 JSON 将只包含我选择的数据,而不是无限深度的关联和递归 :)

Now i can simply select my table, join the associations i need - and my JSON will contain just the data i selected instead of infinite depth associations and recursions :)

$qb= $this->_em->createQueryBuilder()
        ->from("ProjectEntityPersonappointment", 'pa')
        ->select('pa', 't', 'c', 'a')
        ->leftjoin('pa.table', 't')
        ->leftjoin('pa.company', 'c')
        ->leftjoin('pa.appointment', 'a')

JSON 将只包含

{  
  Personappointment: { table {fields}, company {fields}, appointment {fields}}
  Personappointment: { table {fields}, company {fields}, appointment {fields}}
  Personappointment: { table {fields}, company {fields}, appointment {fields}}
  .
  .
}

相关文章