Tôi có một tình huống mà tôi cần phải tham gia các bảng trên một đối tượng trong một hệ thống phân cấp lớp ORM trong đó cột kết nối KHÔNG phải là khóa chính của lớp cơ sở. Dưới đây là một ví dụ về việc thiết kế bảng:Làm cách nào để tôi tham gia các bảng trên các cột chính không phải chính trong bảng phụ?
CREATE TABLE APP.FOO
(
FOO_ID INTEGER NOT NULL,
TYPE_ID INTEGER NOT NULL,
PRIMARY KEY(FOO_ID)
)
CREATE TABLE APP.BAR
(
FOO_ID INTEGER NOT NULL,
BAR_ID INTEGER NOT NULL,
PRIMARY KEY(BAR_ID),
CONSTRAINT bar_fk FOREIGN KEY(FOO_ID) REFERENCES APP.FOO(FOO_ID)
)
CREATE TABLE APP.BAR_NAMES
(
BAR_ID INTEGER NOT NULL,
BAR_NAME VARCHAR(128) NOT NULL,
PRIMARY KEY(BAR_ID, BAR_NAME),
CONSTRAINT bar_names_fk FOREIGN KEY(BAR_ID) REFERENCES APP.BAR(BAR_ID)
)
Và đây là các ánh xạ (getter và setter loại bỏ cho ngắn gọn
@Entity
@Table(name = "FOO")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE_ID", discriminatorType = javax.persistence.DiscriminatorType.INTEGER)
public abstract class Foo {
@Id
@Column(name = "FOO_ID")
private Long fooId;
}
@Entity
@DiscriminatorValue("1")
@SecondaryTable(name = "BAR", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID") })
public class Bar extends Foo{
@Column(table = "BAR", name = "BAR_ID")
Long barId;
}
Làm thế nào tôi có thể thêm các bản đồ cho BAR_NAMES
cho rằng nó tham gia cột không FOO_ID
, nhưng BAR_ID
tôi đã thử những điều sau đây:?
@CollectionOfElements(fetch = FetchType.LAZY)
@Column(name = "BAR_NAME")
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(table = "BAR", name = "BAR_ID", referencedColumnName="BAR_ID"))
List<String> names = new ArrayList<String>();
Điều này không thành công vì SQL để truy xuất đối tượng Bar cố gắng lấy giá trị BAR_ID từ bảng FOO. Tôi cũng đã cố gắng thay thế các chú thích JoinTable với
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(name = "BAR_ID"))
này tạo ra không có lỗi SQL, nhưng cũng lấy không có dữ liệu vì các truy vấn đối với BAR_NAMES đang sử dụng FOO_ID như tham gia giá trị thay vì BAR_ID.
Đối với mục đích thử nghiệm, tôi đã cư DB với các lệnh sau
insert into FOO (FOO_ID, TYPE_ID) values (10, 1);
insert into BAR (FOO_ID, BAR_ID) values (10, 20);
insert into BAR_NAMES (BAR_ID, BAR_NAME) values (20, 'HELLO');
Nhiều giải pháp mà xuất hiện để làm việc sẽ trả về một bộ sưu tập sản phẩm nào khi nhận được đối tượng Foo cho ID 10 (như trái ngược với một bộ sưu tập có chứa 1 tên)
'barId' vẫn được đánh dấu bằng' @ Id', sự khác biệt là gì? – deathangel908