我有一种情况,我需要在 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 个名称的集合)
最佳答案
我找到了解决办法。如果您像这样映射 Bar 类
@Entity
@DiscriminatorValue("1")
@SecondaryTable(name = "BAR", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID") })
public class Bar extends Foo {
@OneToOne
@JoinColumn(table = "BAR", name = "BAR_ID")
MiniBar miniBar;
}
并添加以下类
@Entity
@SqlResultSetMapping(name = "compositekey", entities = @EntityResult(entityClass = MiniBar.class, fields = { @FieldResult(name = "miniBar", column = "BAR_ID"), }))
@NamedNativeQuery(name = "compositekey", query = "select BAR_ID from BAR", resultSetMapping = "compositekey")
@Table(name = "BAR")
public class MiniBar {
@Id
@Column(name = "BAR_ID")
Long barId;
}
然后您可以将您想要的任何类型的映射添加到 MiniBar
类,就好像 barId 是主键一样,然后进一步使其在外部 Bar
类中可用.
关于java - 如何连接辅助表中非主键列的表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1494368/