java - 如何连接辅助表中非主键列的表?

标签 java hibernate orm

我有一种情况,我需要在 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/

相关文章:

java - hibernate native 查询,计数

java - 在 hibernate 状态下可连接多对多

mysql - Node.js、ORM2 和 Mysql。连接未关闭

java - 在 Java 的线程中使用 PreparedStatements 是否正确?

java - 如何在正则表达式中提供 OR 运算符?

hibernate - Grails:如何区分一项交易与另一项交易?

java - 使用 AuditQuery 获取关联实体

mysql - Data Mapper 是不是比 Active Record 更现代的趋势

java - Eclipse 中的 Hibernate 工具 : Change in column values does not reflecting in the query result

Java - 从内存中卸载媒体