【发布时间】:2009-09-29 19:06:36
【问题描述】:
我有一种情况,我需要在 ORM 类层次结构中的对象上连接表,其中连接列不是基类的主键。以下是表格设计的示例:
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 )
)
这里是映射(为简洁起见,删除了 getter 和 setter
@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;
}
如果BAR_NAMES 的连接列不是FOO_ID,而是BAR_ID,我该如何添加映射?
我尝试了以下方法:
@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>();
这会失败,因为用于检索 Bar 对象的 SQL 尝试从 FOO 表中获取 BAR_ID 值。我也尝试将 JoinTable 注释替换为
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(name = "BAR_ID"))
这不会产生 SQL 错误,但也不会检索任何数据,因为针对 BAR_NAMES 的查询使用 FOO_ID 作为连接值而不是 BAR_ID。
出于测试目的,我使用以下命令填充了数据库
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');
当获取 ID 为 10 的 Foo 对象时,许多看似有效的解决方案将返回一个空集合(而不是包含 1 个名称的集合)
【问题讨论】: