Пилот
такой кейс с isInitialized=false только если getResult запроса релейшенов выдал 0 айтемов
Пилот
а мне нужно поставить по сути в initialized=true после этого, ведь это просто айтемов 0, коллекция пустая, и это валидный кейс у меня
Пилот
у этих пустых коллекций
Пилот
а если коллекция гидрирована ДО нормалайзера - то Н+1 нема
Павел
Странно конечно, поидее, это верно что isInitialized=false. Мне кажется где то в другом месте проблема зарыта. Почистите перед каждым запросом для чистоты.
Павел
Без lazy load, до обращения к коллеции, без запроса - не возможно узнать больше 0 или равно 0
Павел
Я бы на шару сказал, что вы где то достали пользователя, он сохранился в identityMap со всему коллекциями isInitialized=false. Потом где то вы обратились в following а к participation нет. Тем самым одну коллекциою проинициализировали, а вторую нет. Потом делаете запросы - но ваш юзер уже прогидрирован и поэтому все add(relation) - просто не срабатывают - пользователь достается из IdenityMap, и там following с isInitialized=true, а participation isInitialized=false.
Павел
Вот если после $em->clear перед каждым запросом такое будет - уже смахивает на баг
Пилот
Я бы на шару сказал, что вы где то достали пользователя, он сохранился в identityMap со всему коллекциями isInitialized=false. Потом где то вы обратились в following а к participation нет. Тем самым одну коллекциою проинициализировали, а вторую нет. Потом делаете запросы - но ваш юзер уже прогидрирован и поэтому все add(relation) - просто не срабатывают - пользователь достается из IdenityMap, и там following с isInitialized=true, а participation isInitialized=false.
там такой флоу) Controller->CustomerForStatisticsQuery->Normalizer в CustomerForStatistics идет кучка таких кверисов как я описал здесь: https://github.com/doctrine/orm/discussions/9997 могу скинуть полный сорец квери-класса, если есть возможность и желание глянуть) а в нормалайзере просто дергается $customer->following(), $customer->participation(), $customer->favourites(), etc, и у этих релейшенов тоже есть свои нестед релейшены, например категории и их транслейшены
Павел
Т.е. если вы сделали первый запрос в котором указали что в коллекции должен быть только релейшен с id=N, то следующий запрос без такого условия все равно вернет сущность с колекцией где тольео 1 релейшен с id=N
Пилот
грубо говоря вот сорец квери класса https://pastebin.com/2dQWGCiE затем $customer возвращается в контроллер, после которого нормалайщер просто обращается к релейшенам, которые УЖЕ должны были быть гидрированы в квери-классе выше, если есть записи, или если нет записей - то хотя бы выставить флажок isInitialized у коллекции релейшена, дабы когда нормалайзер дергает релейшен, он не тригерил лейзи запрос к бд.
Пилот
Ну вот у вас флоу, связанный с кодом вашим, а не чистый эксперимент. Сущности с их коллекциями вроде не перегедрируются
перегидрируются (вроде) ) потому что в participation у меня у кастомера есть записи, и второй запрос гидрирует кастомера, который УЖЕ находится в айдентитимап)
Пилот
а в случае с following кастомер не гидрируется, потому что нет инициатив которые он фоловит. но и isInitialized=false (
Пилот
https://pastebin.com/2dQWGCiE вот кверя
Павел
У вас может где то до query что-то вызывается, обсуждать мало смысла, ну лично я иссяк
Пилот
Короче надо чистый эксперимент, тупо вызывать 3 запроса с em-> clear и уже смотреть
кстати там HINT_REFRESH есть, который позволяет рефрешить записи если они уже есть в идентитимапе. пробовал хинт - тот же результат(
Kirill
Всем привет! Подскажите, как для поля в дострине указать дефолтное значение как текущее время? ORM\Column(name="created_at", type="datetime_immutable", options={"default": "CURRENT_TIMESTAMP"}) Вот такое не работает, в миграции не появляется значение по умолчанию. Gedmo\Timestampable(on="create") не подходит, эта аннотация тоже не устанавливает дефолтное значение на уровне БД, а мне нужно именно на уровне БД)
Kirill
Еще раз, мне нужно, чтобы на уровне БД было значение по умолчанию. Чтобы в миграции было написано created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
Andrii
только что проверил c diff: /** * @ORM\Column(type="datetime", options={"default" : "CURRENT_TIMESTAMP"}) */ private $something; // ... $this->addSql('ALTER TABLE blog ADD something DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, CHANGE short short LONGTEXT NOT NULL, CHANGE body body LONGTEXT NOT NULL');
Dmitriy
дополнить миграцию дефолтным значением
Andrii
дополнить миграцию дефолтным значением
тогда схемы будут разные и валидацию не будут проходить
Andrii
поменял на immutable: ALTER TABLE blog ADD something DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', CHANGE short short LONGTEXT NOT NULL, CHANGE body body LONGTEXT NOT NULL')
Konstantin
columnDefinition еще можно
Andrii
Боже, удалил кеш симфони и действительно все работает. Спасибо большое!
есть такое. doctrine создает кеш сама по себе (к symfony не относится), по-этому да, надо перед каждым diff или после каждого изменения описания entity чистить кеш доктрины, который может быть как в обычном файловом кеше, так и в redis
Юра
Кто разбирается в сериалайзере? Я так понимаю по дефолту он не умеет хендлить массивы объектов?
Юра
Пишут что надо добавить ArrayDenormalizer
Юра
Вопрос как его добавить )
Юра
Создавать свой сериалайзер?
Юра
Или через компайлер пас?
Павел
Ну если дефолтный сериалайзер, в нем уже есть ArrayDenormalizer. Если собирается вручную, то надо добавить ArrayDenormalizer
Павел
Вопрос как его добавить )
Добавление в стандартный сериалайзер любого нормалайзера, денормалайзера и прочего - через теги или на автомате, если стоит автовайринг и приставлен интерфейс к классу.
Юра
Да вроде по дефолту стоит
Юра
Но чет не фурычит
Юра
Вместо массива объектов просто массив массивов
Павел
Вместо массива объектов просто массив массивов
Надо еще add метод добавить с типизацией
Юра
А где об это написано?
Юра
Чет в доке не вижу
Павел
Чет в доке не вижу
Ну там кратенько, что ObjectNormalizer через эти методы работает
Юра
А ка же имутабл дто?
Юра
В пролёте?
Юра
Не умеет что-ли в валью обджект ?
Павел
А ка же имутабл дто?
Видимо да, вроде как только так. Сериалайзер не про имутабельность
Павел
Или писать свои денормалайзеры
Юра
Оч странно короче )
Konstantin
Или писать свои денормалайзеры
которые инжектят свойства через конструктор
Kirill
Всем привет! Подскажите, можно ли как-то у трейта объявить аннотации, чтоб она к классу применялись?
Konstantin
хороший вопрос, но почти точно нет
Konstantin
это на пропертях
Павел
это на пропертях
аа, тогда не понял первоначально
Konstantin
а вот из трейта на сам класс (если я правильно понял вопрос) - то сильно вряд ли
Konstantin
ну типа условный #[Entity] повесить на трейт
Kirill
Ну я проверил, аннотации трейта не читаются. Но вдруг вы знаете, как можно их читать)
Dmitriy
ну не юзай трейты
Юра
Трейты на энтитях. Для чего?
Юра
Я уже видел такой подход. Все плохо обычно
Юра
Например надо будет тебе разные группы сериализации сделать
Юра
Уже не получится
Павел
Трейты на энтитях. Для чего?
Любят всяие общие рилейшены и update/created at
Юра
Ну наверное можно. Только нацти решение возникающих вопросов а виде разных групп сериализации и ещё чего-нибудь разного
Юра
Если оно нужно разное
Юра
С аннотациями это точно работает, должно наверное и с атрибутами работать
Павел
Я например их вообще не юзаю)
Юра
Ну если у тебя дто то не нужны да
Павел
Хотя для какой нить апи платформ - мастхэв
Konstantin
Ну я проверил, аннотации трейта не читаются. Но вдруг вы знаете, как можно их читать)
<?php #[Attribute(Attribute::TARGET_CLASS)] class Attr1 {} #[Attribute(Attribute::TARGET_CLASS)] class Attr2 {} #[Attr1] trait Foo {} #[Attr2] class Cls { use Foo; } $rc = new ReflectionClass(Cls::class); foreach ($rc->getTraits() as $t) { var_dump($t->getAttributes()[0]->getName()); // Attr1 } var_dump($rc->getAttributes()[0]->getName()); // Attr2
Konstantin
если написать свой аттрибут-резолвер, то при желании можно достать