Entitas saya menggunakan anotasi ini untuk ID-nya:
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
Dari database yang bersih, saya mengimpor dalam catatan yang ada dari database yang lebih lama dan mencoba untuk menyimpan ID yang sama. Kemudian, saat menambahkan record baru, saya ingin MySQL menaikkan kolom ID secara otomatis seperti biasa.
Sayangnya, tampaknya Doctrine2 mengabaikan ID yang ditentukan.
Solusi Baru
Sesuai rekomendasi di bawah, berikut ini adalah solusi yang lebih disukai:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Solusi Lama
Karena Doctrine berporos dari ClassMetaData untuk menentukan strategi generator, itu harus dimodifikasi setelah mengelola entitas di EntityManager:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
Saya baru saja menguji ini di MySQL dan berfungsi seperti yang diharapkan, yang berarti Entitas dengan ID khusus disimpan dengan ID itu, sedangkan yang tanpa ID ditentukan menggunakan lastGeneratedId() + 1
.
sumber
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
Jawaban:
Meskipun solusi Anda berfungsi dengan baik dengan MySQL, saya gagal membuatnya berfungsi dengan PostgreSQL karena itu berbasis urutan.
Saya telah menambahkan baris ini agar berfungsi dengan sempurna:
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Salam Hormat,
sumber
$em->persist($entity)
.Mungkin doktrin apa yang berubah tetapi sekarang cara yang benar adalah:
sumber
ClassMetadata
merupakan antarmuka dan karenanya tidak dapat memiliki konstanta.$metadata::GENERATOR_TYPE_NONE
Jika entitas adalah bagian dari warisan tabel kelas, Anda perlu mengubah pembuat-id di metadata kelas untuk kedua entitas (entitas yang Anda pertahankan dan entitas akar)
sumber
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
kesalahan. DownvotedSolusi baru berfungsi dengan baik hanya jika SEMUA entitas memiliki id sebelum dimasukkan. Ketika satu entitas memiliki ID dan entitas lainnya tidak - solusi baru gagal.
Saya menggunakan fungsi ini untuk mengimpor semua data saya:
sumber
Solusi untuk Doctrine 2.5 dan MySQL
"Solusi baru" tidak berfungsi dengan Doctrine 2.5 dan MySQL. Anda harus menggunakan:
Namun saya hanya dapat mengkonfirmasi itu untuk MySQL, karena saya belum mencoba DBMS lainnya.
sumber
Saya telah membuat perpustakaan untuk menetapkan ID masa depan untuk entitas Doktrin. Ini kembali ke strategi pembuatan ID asli ketika semua ID antrean digunakan untuk meminimalkan dampak. Ini harus menjadi drop-in yang mudah untuk pengujian unit sehingga kode seperti ini tidak perlu diulang.
sumber
Terinspirasi oleh karya Villermen , saya membuat perpustakaan tseho / doktrin-ditugaskan-identitas yang memungkinkan Anda untuk menetapkan ID secara manual ke entitas Doktrin, bahkan ketika entitas menggunakan status AUTO, SEQUENCE, IDENTITY atau UUID.
Anda tidak boleh menggunakannya dalam produksi tetapi ini sangat berguna untuk pengujian fungsional.
Library akan mendeteksi secara otomatis entitas dengan id yang ditetapkan dan mengganti generator hanya jika diperlukan. Pustaka akan fallback pada generator awal ketika sebuah instance tidak memiliki id yang ditetapkan.
Penggantian generator terjadi di Doctrine EventListener, tidak perlu menambahkan kode tambahan apa pun di perlengkapan Anda.
sumber