I'm facing a problem with a custom id generator, auto-incrementation and doctrine-migrations in Symfony (2.7) with Doctrine (2.5) and MySQL.
When I use the custom generator, the id field does not get the AUTO_INCREMENT status in the migrations:diff output. When I add the autoincrement manually in the yaml then all referenced table-columns also get the AUTO_INCREMENT.
How can I use auto increment on my primary entity with a custom generator without affecting the references?
The entity (sites.orm.yml):
type: entity
table: sites
id:
id:
type: integer
column: id
generator:
strategy: CUSTOM
customIdGenerator:
class: AssignableIdentityGenerator
The generator:
class AssignableIdentityGenerator extends AbstractIdGenerator {
public function generate(EntityManager $em, $entity) {
return $entity->getId() ? : (int) $em->getConnection()->lastInsertId();
}
public function isPostInsertGenerator() {
return true;
}
}
Migrations:diff output keeps being this (removes the AUTO_INCREMENT):
ALTER TABLE sites CHANGE id id INT NOT NULL;
If I add
options:
autoincrement: true
I don't get an ALTER for the sites table, which is correct because it keeps the AUTO_INCREMENT, but instead I get
ALTER TABLE other_table CHANGE site_id site_id INT AUTO_INCREMENT NOT NULL;
on a referencing table, which is not correct.
Doctrine natively suports the AUTO_INCREMENT with its own IdentityGenerator and I think I found the spot in Doctrine\\ORM\\Tools\\SchemaTool::gatherColumn where this takes effect, but it's deep in a private method:
if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) {
$options['autoincrement'] = true;
}
Unfortunately Doctrine is not very friendly to extensions (many private methods/properties or classes being instantiated instead of using injectable services).
Would anyone have a solution to this problem? Or maybe even a whole different idea on how to get an id field that is both auto-incrementable and manually settable.
Would anyone have a solution to this problem? Or maybe even a whole different idea on how to get an id field that is both auto-incrementable and manually settable.
I got this solution for you:
First: You need to set up your ID strategy to "AUTO"
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
Second: If you want to set up your ID manually, you need to change the metadata ( before flush ) of your class. There you can change your IdGeneratorType
/**
* @param EntityManager $em
* @param mixed $object
*/
protected function changeIdGeneratorType(EntityManager $em, $object)
{
if ($object->getId() !== null) {
$metadata = $em->getClassMetadata(get_class($object));
$metadata->setIdGeneratorType($metadata::GENERATOR_TYPE_NONE);
}
}
$metadata::GENERATOR_TYPE_NONE
With this GeneratorType you will be able to set your ID's manually.
Now you will be able to both auto-incrementable and manually settable ID's
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.