2012-03-14 42 views
10

Làm thế nào để bỏ qua các mục trùng lặp bằng Doctrine2?chèn bỏ qua các mục trùng lặp trong Doctrine2/Symfony2

Lỗi dụ:

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

Bạn có thể làm những gì thúc đẩy làm: tạo ra một phương pháp như findByKeyOrCreate(), trả lại một thực thể tồn tại nếu có hoặc tạo một cái mới nếu không muốn nói. – gremo

+0

Xóa chỉ mục '@ Unique' khỏi trường đó, nếu bạn không cần nó. –

+0

Rõ ràng là tôi cần nó ... – seferov

Trả lời

11

Đó là một trong những phiền toái của Doctrine, không thể thực hiện INSERT/UPDATE Bỏ qua, có cách giải quyết như tạo một phương thức kiểm tra nếu hàng tồn tại, và nếu có thì chỉ cần bỏ qua.

Bạn có thể bắt ngoại lệ, do đó tập lệnh của bạn không kết thúc bằng ngoại lệ. Tuy nhiên, người quản lý thực thể sẽ bị đóng và bạn sẽ không thể sử dụng nó nữa. Bạn vẫn có thể sử dụng PDO, và bạn có thể chèn một bản ghi trong cơ sở dữ liệu cho biết rằng lô của bạn không thành công vì X và nó cần được khởi động lại (đó là những gì tôi thường làm).

Nếu không có tùy chọn nào phù hợp với bạn, cuối cùng tôi sẽ viết SQL thô để thực hiện xử lý hàng loạt và tôi không sử dụng Doctrine, nó sẽ nhanh hơn và khả năng thực hiện INSERT/UPDATE Ignore nó không có trí tuệ.

9

Bạn luôn có thể nắm bắt những ngoại lệ và sau đó bỏ qua nó. Chỉ cần lưu ý rằng khi người quản lý thực thể đưa ra một ngoại lệ, người quản lý thực thể không còn có thể được sử dụng trong yêu cầu đó nữa.

7

Trong Symfony 3 bạn có thể thiết lập lại quản lý và tiếp tục làm việc với nó bằng cách gọi resetManager() phương pháp Doctrine đối tượng sau khi bắt UniqueConstraintViolationException ngoại lệ.

Dưới đây là một ví dụ:

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

Chia sẻ tuyệt vời! (ví dụ: resetManager()) –

+1

Tôi sẽ quan tâm đến một câu trả lời gần đây hơn về loại đó. resetManager() hiện không còn được dùng nữa. – Moonchild

+0

nếu bạn đang sử dụng symfony 3/4 sử dụng 'nhà soạn nhạc yêu cầu symfony/proxy-manager-bridge' –

Các vấn đề liên quan