я хотел бы реализовать удобочитаемый идентификатор в моей доктрине-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». Есть ли другой способ его реализации?
Из того, что я знаю, стратегия GeneratedValue зарезервирована для первичного ключа, то есть вы можете использовать ее только один раз для Entity.
В зависимости от ваших потребностей у вас есть несколько вариантов:
У вас всегда может быть событие жизненного цикла prePersist , задавая любое значение, которое вам нравится для имени, прежде чем вы его персистеете в первый раз.
Если вы используете идентификатор для создания другого уникального идентификатора, вы можете реализовать событие postPersist, установить там свое имя и убедиться, что вы дважды сбросили (первый раз для создания первичного ключа, второй раз для сохранения имени).
Если вам хорошо, что имя пустое в базе данных в течение некоторого времени, может быть нормально реализовать событие postLoad, которое заполняет имя, если оно пустое. Таким образом, ваше приложение всегда видит имя (потому что оно либо загружается из базы данных, либо заполняется событием postLoad), и когда вы добавляете или редактируете информацию в первый раз после первоначального сохранения, ваше имя также будет сохранено
Было бы неплохо сохранить имя и создать его с помощью cronjob / deamon / queue, чтобы ваше приложение не занималось этим. Единственное, что вам нужно сделать, это убедиться, что пропущенное имя ничего не испортит.
Возможно, было бы нормально создавать ключ, который не зависит от первичного ключа и, следовательно, может быть сгенерирован глобальным обработчиком событий . Конечно, у вас есть недостаток, что такой обработчик событий, потому что он глобальный, получает вызов для каждого объекта, который вы сохраняете, независимо от того, является ли он правильной сущностью.
Последнее, но не менее важно, может быть, стоит отказаться от хранимых процедур / триггеров, чтобы позволить базе данных справиться с этим. Таким образом, вам не нужно возиться с этим в своем приложении. Но будьте осторожны, на пути могут возникнуть проблемы (как разработчик забывает об этом, потому что это не в коде, а в базе данных!).
Могут быть и другие способы. Я пытался сказать: не используйте generateValue для свойств не первичного ключа!