Два генерируемых значения в доктрине - программирование
Подтвердить что ты не робот

Два генерируемых значения в доктрине

Я хотел бы внедрить удобочитаемый идентификатор в моей доктрине-Entity. Я хочу, чтобы DB-ID работал и добавлял что-то вроде "PRE12-00005" (с префиксом и годом и начинался с 0 каждый новый год). Я попытался добавить Custom-ID-Generator, но кажется, что Doctrine не может работать с двумя сгенерированными значениями в одном Entity.

/**
 * @var integer
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
protected $id;

/**
 * @var string
 * @ORM\Column(name="name", type="string", length=25, unique=true)
 * @ORM\GeneratedValue(strategy="CUSTOM")
 * @ORM\CustomIdGenerator(class="NameGenerator")
 */
protected $name;

Doctrine всегда пытается сохранить возвращаемое значение из моего генератора в "id" -Field и null в "name". Есть ли другой способ его реализации?

4b9b3361

Ответ 1

Из того, что я знаю, стратегия GeneratedValue зарезервирована для первичного ключа, то есть вы можете использовать ее только один раз для каждой сущности.

В зависимости от ваших потребностей у вас есть несколько вариантов:

  • Вы можете всегда иметь событие жизненного цикла prePersist, устанавливая любое значение для имени, прежде чем сохранить его в первый раз.

  • Если вы полагаетесь на идентификатор для создания другого уникального идентификатора из него, вы можете реализовать событие postPersist, указать там свое имя и дважды очистить его (первый раз для генерации первичного ключа, второй раз для сохранения имени).

  • Если для вас нормально, что имя в базе данных какое-то время пустое, было бы хорошо реализовать событие postLoad, которое заполняет имя, если оно пустое. Таким образом, ваше приложение всегда видит имя (потому что оно загружено из базы данных или заполнено событием postLoad), и когда вы добавляете или редактируете информацию в первый раз после первоначального сохранения, ваше имя также будет сохранено.

  • Может быть нормально не сохранять имя и генерировать его с помощью некоторого cronjob/deamon/queue, чтобы ваше приложение не имело с этим дело. Единственное, что вам нужно сделать, это убедиться, что пропущенное имя ничего не испортило.

  • Возможно, было бы неплохо сгенерировать ключ, который не зависит от первичного ключа и, следовательно, может быть сгенерирован глобальным обработчиком событий. У вас, конечно, есть недостаток в том, что такой обработчик событий, потому что он глобальный, вызывается для каждого сохраняемого объекта, независимо от того, является ли он правильным объектом.

  • И последнее, но не менее важное: может быть нормально вернуться к хранимым процедурам/триггерам, чтобы позволить базе данных справиться с этим. Таким образом, вам не нужно связываться с этим внутри вашего приложения. Но будьте осторожны, на пути могут быть подводные камни (например, разработчик забывает об этом, потому что это не в коде, а в базе данных!).

Могут быть и другие способы. То, что я пытался сказать, это: не используйте generateValue для свойств не первичного ключа!