С этими классами, как бы вы изменили запись для «Лица» на «Сотрудник».
/** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... }
Я попытался изменить значение столбца дискриминатора, но я не могу получить к нему доступ. Я также попытался создать экземпляр «Employee» и вручную скопировать данные, но это не работает с автоматически увеличивающимися идентификаторами. Он просто добавляется как новая запись вместо обновления существующего.
Нужно ли писать собственный SQL-запрос или я делаю что-то еще, что в корне неверно?
Это не хороший знак, когда тип экземпляра объекта должен меняться со временем. Я не говорю о понижении / повышении рейтинга здесь, а о необходимости изменить реальный тип объекта.
Прежде всего, позвольте мне сказать вам, почему это плохая идея:
Это связано с тем, что большинство языков не позволят вам изменить тип реального класса объекта во время выполнения (и, конечно, память, но я не хочу вдаваться в подробности). Некоторые позволяют вам это делать (иногда в скрученном виде, например, JVM), но это действительно не очень хорошая практика!
Чаще всего необходимость в этом заключается в плохих объектно-ориентированных проектных решениях.
По этим причинам Doctrine не позволит вам изменить тип объекта объекта. Конечно, вы могли бы написать простой SQL (в конце этого сообщения, но, пожалуйста, прочитайте!), Чтобы сделать изменение в любом случае, но вот два «чистых» варианта, которые я бы предложил:
Я понимаю, вы уже сказали, что первый вариант не был вариантом, но я потратил некоторое время на запись этого сообщения, поэтому я чувствую, что должен сделать его максимально полным для будущей справки.
Person
to Employee
, создайте новый экземпляр Employee и скопируйте данные, которые вы хотите скопировать из старого объекта Person, в объект Employee. Не забудьте удалить старый объект и сохранить новый. См. Соответствующие обсуждения здесь и здесь .
Теперь, вот простой метод SQL, о котором я говорил раньше, надеюсь, вам не понадобится его использовать!
Убедитесь, что ваш запрос очищен (так как запрос будет выполнен без какой-либо проверки).
$query = "UPDATE TABLE_NAME_HERE SET discr = 'employee' WHERE id = ".$entity->getId(); $entity_manager->getConnection()->exec( $query );
Вот документация и код метода exec, который находится в классе DBAL\Connection
(для вашей информации):
/** * Execute an SQL statement and return the number of affected rows. * * @param string $statement * @return integer The number of affected rows. */ public function exec($statement) { $this->connect(); return $this->_conn->exec($statement); }