2011-08-12 32 views
16

Tôi đang gặp sự cố với ánh xạ của mình. Tôi không thể có được nó để làm việc. Tôi có một lớp cơ sở trừu tượng như vậy:Thừa kế lớp bảng giáo lý khi một lớp con không có thuộc tính phụ

/** 
* @Entity 
* @Table(name="actions") 
* @InheritanceType("JOINED") 
* @DiscriminatorColumn(name="type", type="string") 
* @DiscriminatorMap({"FOO" = "FooAction", "BAR" = "BarAction", ...}) 
*/ 
abstract class AbstractAction 
{ 
    ... 
} 

Tôi có một loạt các hành động khác nhau, tất cả đều có các trường khác nhau. Ví dụ:

/** 
* @Entity 
* @Table(name="actions_foo") 
*/ 
class FooAction extends AbstractAction 
{ 
    ... 
} 

Nhưng một trong những hành động của tôi (BarAction) không cần bất kỳ trường bổ sung bên cạnh những cung cấp bởi AbstractAction. Nhưng làm thế nào tôi có thể lập bản đồ đó? Tôi đã thử bỏ qua số @Table hoặc sử dụng cùng một @Table làm AbstractAction nhưng không có hiệu lực.

/** 
* @Entity 
* @Table(name="actions") 
*/ 
class BarAction extends AbstractAction 
{ 
    ... 
} 

Bỏ các @Table mang lại cho tôi một PDOException về một bảng thiếu BarAction. Sử dụng số @Table của lớp cơ sở cung cấp cho tôi:

PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens 

Vì vậy, làm cách nào để ánh xạ điều này?

Chỉnh sửa: Cho đến nay tôi đã thử hai thứ khác.

Tôi đã thử xóa @Entity cũng như @Table từ BarAction với hy vọng rằng cách này sẽ không yêu cầu bảng cơ sở dữ liệu nữa. Điều đó không hiệu quả. Thay vào đó, tôi nhận được lỗi này:

Doctrine\ORM\Mapping\MappingException: Class BarAction is not a valid entity or mapped super class. 

Tiếp theo, tôi cố gắng tạo ra một bảng actions_bar trong cơ sở dữ liệu của tôi với chỉ một số nước ngoài cột then chốt id. Sau đó tôi vẽ bản đồ số BarAction. Điều đó hoạt động (yay!) Nhưng nó cảm thấy crufty và xấu xí để có thêm một bảng SQL mà tôi không cần gì cả.

Vì vậy, vẫn đang tìm kiếm một cách tốt hơn ...

+0

được thêm vào kinh nghiệm 2 năm của tôi với D2 và [tài liệu] này (http://www.doctrine-project.org/docs/orm/2.0/en/reference/inheritance-mapping.html#class-table-inheritance), bạn chỉ có thể đi với một loại thừa kế. Hoặc bạn chọn kế thừa bảng đã nối và có một bảng riêng cho mỗi thực thể hoặc chọn một bảng kế thừa đơn và có tất cả các thực thể của bạn trong một bảng. (bình luận được thêm vào cho WizardZ, người chưa có đại diện để nhận xét) – Oded

+4

Dựa trên kinh nghiệm 2 năm của tôi với D2 và tài liệu: http://www.doctrine-project.org/docs/orm/2.0/en/reference/ inheritance-mapping.html # class-table-inheritance bạn có thể chỉ đi với một kiểu thừa kế. Hoặc bạn chọn kế thừa bảng đã nối và có một bảng riêng cho mỗi thực thể hoặc chọn một bảng kế thừa đơn và có tất cả các thực thể của bạn trong một bảng. – WizardZ

+0

@Sander: 'BarAction' của bạn có thực sự là lớp con của' AbstractAction' không? Tôi không biết nếu nó có ý nghĩa trong mô hình miền của bạn để có 'BarAction' là gốc của hệ thống phân cấp, nhưng từ một quan điểm thực hiện, điều đó sẽ giải quyết vấn đề của bạn, vì' BarAction' sẽ chỉ sử dụng các trường từ bảng cơ sở! – Benjamin

Trả lời

2

Bạn đang sử dụng joined mô hình thừa kế (thừa kế bảng lớp), sử dụng bảng riêng cho cha mẹ và mỗi con. Nếu bạn không chỉ định bất kỳ trường nào trong lớp con, Doctrine sẽ chỉ tạo một bảng chỉ chứa trường ID.

Và lớp cha chỉ có thể sử dụng một loại thừa kế, kế thừa bảng lớp hoặc thừa kế bảng đơn.

Trong trường hợp đó, nếu bạn không muốn có bảng chỉ có cột id trong đó, bạn cần phải thay đổi mô hình dữ liệu của mình.

2

Có thể điều này có thể giúp hoặc thêm nội dung mới. Nó không phải là cách trả lời mà chỉ đơn giản là lấy các khái niệm. Nếu bạn nghĩ về các lớp và bạn hiểu mô hình của mình là: AbstractAction, FooAction và BarAction, có lẽ vì bạn có thể thực hiện cùng một phương thức theo cách khác trên các lớp con hoặc mở rộng một số phương thức cha.

Nếu bạn chọn đại diện cho các lớp này với bảng và bạn chọn "tất cả trong một bảng có thuộc tính phân biệt đối xử", tôi nghĩ bạn không có vấn đề gì. Đối với BarAction, bạn sẽ có đăng ký với discriminator = "BarAction" sẽ được repenterented bởi một lớp thực thể BarAction.php.

Mặt khác, nếu bạn chọn sử dụng bảng khác, tôi cho rằng bạn cần một bảng cho mỗi "lớp". Bảng cho BarAction sẽ chỉ bao gồm trường ID cho AbstractAction nhưng nó được yêu cầu để "phân loại" (hoặc phân biệt) dữ liệu của bạn như là một FooAction.

Tóm lại, tôi nghĩ ba bảng biểu diễn ba lớp là một giải pháp tốt, mặc dù bảng BarAction chỉ chứa một "liên kết" tới bảng cha.

0

Tôi nghĩ bạn không phải tạo bảng theo cách thủ công trong cơ sở dữ liệu của mình.

Tôi có khá nhiều cấu trúc giống nhau nên tôi để Doctrine (2.3) thực hiện công việc. Bạn phải đặt @Entity et @Table trên mỗi lớp con. Lỗi Số tham số không hợp lệ: số biến bị ràng buộc không khớp với số mã thông báo có thể không liên quan. Nó có thể là một vấn đề bộ nhớ cache, bạn đã thử xả nó?

0

Tôi cũng gặp phải vấn đề này, nhưng tôi chỉ thêm một số thuộc tính giả vào thực thể thừa kế của tôi, nghĩ rằng nó có thể hữu ích bất cứ lúc nào. Tôi biết nó không phải là ý tưởng hoàn hảo, nhưng nó đã giúp tôi giữ nguyên mô hình dữ liệu của mình và cho tôi khả năng có tài sản riêng trong các thực thể thừa hưởng trong tương lai.

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