Moja jednostka używa tej adnotacji jako swojego identyfikatora:
/**
* @orm:Id
* @orm:Column(type="integer")
* @orm:GeneratedValue(strategy="AUTO")
*/
protected $id;
Z czystej bazy danych importuję istniejące rekordy ze starszej bazy danych i staram się zachować te same identyfikatory. Następnie podczas dodawania nowych rekordów chcę, aby MySQL jak zwykle automatycznie zwiększał wartość kolumny ID.
Niestety, wygląda na to, że Doctrine2 całkowicie ignoruje podany identyfikator.
Nowe rozwiązanie
Zgodnie z poniższymi zaleceniami preferowanym rozwiązaniem jest:
$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());
Stare rozwiązanie
Ponieważ Doctrine opiera się na ClassMetaData w celu określenia strategii generatora, musi zostać zmodyfikowana po zarządzaniu encją w EntityManager:
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$this->em->flush();
Właśnie przetestowałem to na MySQL i działało zgodnie z oczekiwaniami, co oznacza, że jednostki z niestandardowym identyfikatorem były przechowywane z tym identyfikatorem, podczas gdy te bez określonego identyfikatora używały rozszerzenia lastGeneratedId() + 1
.
źródło
$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
Odpowiedzi:
Chociaż twoje rozwiązanie działa dobrze z MySQL, nie udało mi się go uruchomić z PostgreSQL, ponieważ jest oparte na sekwencji.
Muszę dodać tę linię, aby działała idealnie:
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
Z poważaniem,
źródło
$em->persist($entity)
.Być może zmieniła się doktryna, ale teraz jest właściwa:
źródło
ClassMetadata
jest interfejsem i dlatego nie może mieć żadnych stałych.$metadata::GENERATOR_TYPE_NONE
W przypadku, gdy jednostka jest częścią dziedziczenia tabeli klas , musisz zmienić generator id w metadanych klasy dla obu jednostek (encja, którą utrwalasz, i jednostka główna)
źródło
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
błędy. DownvotedNowe rozwiązanie działa dobrze tylko wtedy, gdy WSZYSTKIE podmioty mają identyfikator przed wstawieniem. Gdy jeden podmiot ma identyfikator, a inny nie - nowe rozwiązanie zawodzi.
Używam tej funkcji do importu wszystkich moich danych:
źródło
Rozwiązanie dla Doctrine 2.5 i MySQL
„Nowe rozwiązanie” nie działa z Doctrine 2.5 i MySQL. Musisz użyć:
Jednak mogę to tylko potwierdzić dla MySQL, ponieważ nie próbowałem jeszcze żadnego innego DBMS.
źródło
Utworzyłem bibliotekę do ustawiania przyszłych identyfikatorów dla encji Doctrine. Powraca do oryginalnej strategii generowania identyfikatorów, gdy wszystkie identyfikatory w kolejce są zużywane, aby zminimalizować wpływ. Powinien to być łatwy dodatek do testów jednostkowych, aby taki kod nie musiał być powtarzany.
źródło
Zainspirowany pracą Villermena , stworzyłem bibliotekę tseho / doctrine-assign-identity, która pozwala na ręczne przypisywanie identyfikatorów do encji Doctrine, nawet jeśli encja korzysta ze strategii AUTO, SEQUENCE, IDENTITY lub UUID.
Nigdy nie powinieneś używać go w produkcji, ale jest naprawdę przydatny do testów funkcjonalnych.
Biblioteka automatycznie wykryje jednostki z przypisanym identyfikatorem i zastąpi generator tylko wtedy, gdy będzie to potrzebne. Biblioteka powróci do początkowego generatora, gdy instancja nie ma przypisanego identyfikatora.
Zastąpienie generatora następuje w Doctrine EventListener, nie ma potrzeby dodawania dodatkowego kodu do urządzeń.
źródło