2012-03-28 24 views
11

Trước khi tôi mô tả vấn đề của tôi, nó có thể thực sự làm cho nó rõ ràng hơn nếu tôi bắt đầu với lỗi tôi nhận được:thuyết nhiều-nhiều mối quan hệ muốn tạo ra một bảng hai lần khi tôi tạo một sự chuyển đổi

$ ./app/console doc:mig:diff 

    [Doctrine\DBAL\Schema\SchemaException]     
    The table with name 'user_media_area' already exists. 

Điều đó hoàn toàn đúng - user_media_area không tồn tại. Tôi đã tạo nó trong lần di chuyển trước và tôi không hiểu tại sao Symfony lại cố gắng tạo bảng.

Vấn đề của tôi có liên quan đến mối quan hệ nhiều-nhiều. Tôi có một bảng gọi là user, một bảng có tên là media_area và một bảng có tên là user_media_area.

Dưới đây là đoạn code mà tôi nói user về media_area (Entity/User.php):

/** 
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas") 
* @JoinTable(name="user_media_area", 
*  joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@JoinColumn(name="media_area_id", referencedColumnName="id")} 
*  ) 
*/ 
private $mediaAreas; 

Và đây là nơi mà tôi nói media_area về user (Entity/MediaArea.php):

/** 
* @ORM\ManyToMany(targetEntity="User", mappedBy="users") 
*/ 
private $users; 

Điều thú vị là nếu tôi loại bỏ công cụ JoinTable từ Entity/User.php, ./app/console doctrine:migrations:diff sẽ hoạt động trở lại:

/** 
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas") 
*/ 
private $mediaAreas; 

Tuy nhiên, hơi một chút: bây giờ muốn tạo một bảng mới có tên là mediaarea mà tôi không muốn. Bảng của tôi đã tồn tại và nó được gọi là media_area.

Vì vậy, nó trông giống như một trong hai cách, Symfony đang cố gắng để tạo ra một bảng dựa trên ManyToMany điều này trong lớp User của tôi, và lý do duy nhất vấn đề đi xa khi tôi loại bỏ các JoinTable là tên của bảng nó muốn để tạo (mediaarea) không còn khớp với tên thực tế của bảng của tôi (media_area).

Vì vậy, câu hỏi của tôi là: Tại sao nó muốn tạo một bảng mới? Tôi đang làm gì sai?

(Tôi biết nó có thể là quy ước đặt tên của tôi đang tắt. Symfony và các ví dụ cơ sở dữ liệu Giáo lý của rất phiền không có các tên cột đa hạn, vì vậy tôi không bao giờ biết nếu tôi phải làm media_area hoặc mediaArea.)

Trả lời

4

Theo Association Mapping giải thích về các tài liệu chính thức, @JoinColumn@JoinTable định nghĩa thường không bắt buộc và có giá trị mặc định hợp lý, là:

name: "<fieldname>_id" 
referencedColumnName: "id" 

Từ đó chúng ta có thể kết luận rằng có thực sự là không có khác biệt cụ thể giữa hai lần triển khai bạn đã trình bày.

Tuy nhiên, khi nói đến di chuyển, việc tạo bảng là hành vi khá phổ biến và được mong đợi. Vấn đề là bảng nên luôn bị xóa và tạo lại, điều này không xảy ra.

Về vấn đề tên bảng, hành vi mặc định của Học thuyết 2 về vấn đề này:

/** 
* @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas") 
*/ 
private $mediaAreas; 

là để thử và tạo ra một bảng gọi là mediaarea. Một lần nữa, hoàn toàn bình thường.

Nếu bạn muốn khai báo một tên cụ thể cho bảng của một tổ chức nào, bạn nên làm điều này:

/** 
* @ORM\Table(name="my_table") 
*/ 
class Something 

Tôi không chắc chắn nếu điều đó giúp bạn ở tất cả, nhưng tôi đoán nó đặt bạn, ít nhất, đi đúng hướng.

+3

Tại sao điều này được đánh dấu là câu trả lời? Nó không trả lời câu hỏi của OP về cách ngăn giáo lý hiển thị lỗi đó. Sau khi thêm vào, tôi nhận Doctrine \ Common \ Annotations \ AnnotationException: [Semantical Error] Chú thích @ORM \ Table không được phép khai báo trên thuộc tính User :: $ mediaAreas. Bạn chỉ có thể sử dụng chú thích này trên các phần tử mã sau: CLASS. – jaycode

+0

Bạn đang cố gắng đặt chú thích '@ ORM/Table' ở cấp thuộc tính, trong khi nó sẽ được đặt ở cấp lớp. Lỗi không liên quan gì đến câu hỏi hoặc câu trả lời. –

+0

Chú thích chính xác là @ ORM/JoinTable – luliandro

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