2012-03-14 9 views
10

Jak zignorować duplikaty wpisów za pomocą Doctrine2?wstawić ignoruj ​​po duplikatach wpisów w Doctrine2/Symfony2

przykładem błędu:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'symfony' for key 'UNIQ_389B783389B783' 
+0

Możesz robić co napędzać zrobić: uczynić metodę jak findByKeyOrCreate(), zwrócenie istniejący podmiot ewentualne lub utworzenie nowego, jeśli nie. – gremo

+0

Usuń z tego pola indeks "@ Unique", jeśli go nie potrzebujesz. –

+0

Oczywiście potrzebuję tego ... – seferov

Odpowiedz

11

To jedna z uciążliwości Doctrine, nie można wykonać INSERT/UPDATE Ignoruj, istnieją obejścia takie jak tworzenie metod sprawdzających, czy wiersz istnieje, a jeśli tak, to po prostu pomiń go.

Możesz przechwycić wyjątek, aby skrypt nie zakończył się wyjątkiem. Jednak menedżer encji zostanie zamknięty i nie będzie można już z niego korzystać. Nadal możesz używać PDO i możesz wstawić rekord do bazy danych, wskazując, że twoja partia nie powiodła się, ponieważ X i musi zostać ponownie uruchomiona (zwykle to robię).

Jeśli żadna z powyższych opcji nie działa, ostatecznie kończę pisanie surowego kodu SQL do przetwarzania wsadowego, a ja w ogóle nie używam Doctrine, w efekcie kończy się to szybciej, a możliwość wykonania INSERT/UPDATE Ignoruje to nie myślenia.

9

Zawsze można złapać wyjątek, a następnie go zignorować. Należy pamiętać, że gdy menedżer encji zgłasza wyjątek, menedżer encji nie może już być używany podczas tego żądania.

7

W Symfony 3 można przywrócić menedżera i kontynuować pracę z nim przez wywołanie resetManager() metodę Doctrine obiektu po łapania UniqueConstraintViolationException wyjątek.

Oto przykład:

try { 
    $em = $this->getDoctrine()->getManager(); 
    $entity = Product::create() 
    ->setTitle('Some title') 
    ->setUrl('http://google.com'); 
    $em->persist($entity); 
    $em->flush(); 
} 
catch (UniqueConstraintViolationException $e) { 
    $this->getDoctrine()->resetManager(); 
} 
+1

Niezły udział! (tj. resetManager()) –

+1

Byłbym zainteresowany nowszą odpowiedzią tego typu. resetManager() jest teraz przestarzałe. – Moonchild

+0

jeśli używasz Symfony 3/4 używaj 'Kompozytor wymaga symfony/proxy-manager-bridge' –

Powiązane problemy