KerryDarko
@KerryDarko

Doctrine: связь один-к-одному в аннотациях: почему сразу же срабатывает «ленивая» загрузка?

У меня есть две сущности со связью один-к-одному, описанной в аннотациях
/**
     * @ORM\OneToOne(targetEntity="Subdomain", mappedBy="company")
     */
    protected $subdomain;

    ...

    /**
     * @ORM\OneToOne(targetEntity="Company", inversedBy="subdomain")
     * @ORM\JoinColumn(name="target_id", referencedColumnName="id")
     */
    private $company;


В документации есть пример:

$product = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->find($id);

    $categoryName = $product->getCategory()->getName();

И сказано:

When you call $product->getCategory()->getName(), Doctrine silently makes a second query to find the Category that's related to this Product.

What's important is the fact that you have easy access to the product's related category, but the category data isn't actually retrieved until you ask for the category (i.e. it's "lazily loaded").


А если написать query руками:
$repository = $this->get('doctrine')->getRepository('TestBundle:Company');

    $qb = $repository->createQueryBuilder('c');
    $qb
            ->where('(c.id = :id)')
            ->setParameter('id', 1);
    $query = $qb->getQuery();

    $val = $query->getOneOrNullResult();


То к базе идет сразу два запроса: выборка компании и выборка субдомена.
Почему так?
  • Вопрос задан
  • 1250 просмотров
Решения вопроса 1
@vendetto
Это давно известное поведение, ответ по ссылке.

Решение: оставить связь только со стороны владельца - это сущность, которая имеет связь. В Вашем случае Subdomain. Или изменить владельца.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
привет, ребятки!
на самом деле не совсем понятен вопрос. по крайней мере лично мне

при выборке объектов через find используется ленивая загрузка: для объектнов AppBundle:Product выбираются все его поля, а для всех отношений формируются прокси-объекты, через которые через дополнительные запросы к БД можно получить и сами объекты отношений

есть нюанс при использовании DQL:
  • когда Вы не прописываете ничего в select, то выбираются все поля объекта (для отношений все так же готовятся прокси)
  • когда вы прописываете в select нужные Вам поля объекта, то только они и выбираются (для отношений все так же готовятся прокси)
  • а вот если вы пропишите в select выборку отношений и укажете join, то будет выполнен запрос с джоином и сразу будут выбраны соответствующие объекты отношений


возможно, Вы что-то упустили? в одном случае Вы обращаетесь к AppBundle:Product, во втором к TestBundle:Company и говорите о выборке субдомена

ленивая загрузка происходит всегда если вы не используете join, или явно не указываете что нужно fetch-ить сущности отношений как EAGER
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы