我有以下方案:TableA1和TableA2存在于数据库中,每个都由实体bean表示。由于它们是相关的,我创建了一个抽象类(TableA,它是一个实体但在数据库中不存在),其中两个实体都从这个类继承。此外,TableA与TableB具有一对一的关系。
我的目标是查询TableB,并从中获取TableA1或TableA2的信息,具体取决于类型。
TableA1和TableA2每个都有一个id(每个表自动生成一个序号,所以你可能会重复)。
在TableB中,我有两个组合表示外键的列:type和id。 Type = 1表示id在TableA1中。与TableA2类似。
我的问题是我不知道如何将这两列定义为外部外键。 这就是我所拥有的:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name="type")
public abstract class TableA {
@Id
@Column(name = "type")
protected int type;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
protected int id;
@Column(name = "name")
private String name;
// Getters and setters
}
@Entity
@DiscriminatorValue("1")
@Table (name="tableA1")
public class TableA1 extends TableA {
@Column(name="col1")
private String col1;
// Getters and setters
}
@Entity
@DiscriminatorValue("2")
@Table (name="tableA2")
public class TableA2 extends TableA {
@Column(name="col2")
private String col2;
// Getters and setters
}
@Entity
@Table (name="tableB")
public class TableB {
@Id
@Column(name="someId")
private Integer someId;
@Column(name="type")
private int type;
@Column(name="id")
private Integer id;
@OneToOne(optional = false, cascade = CascadeType.ALL)
@JoinColumns({
@JoinColumn(name = "type"),
@JoinColumn(name = "id" )
})
private TableA tableA;
// Getters and setters
}
更新
我在寻找不可能的事吗?这是我发现的:
每个类表层次结构中与非叶类的多态关系有许多限制。当具体子类未知时,相关对象可以在任何子类表中,从而无法通过关系进行连接。这种歧义也会影响身份查找和查询;这些操作需要多个SQL SELECT(每个可能的子类一个)或复杂的UNION。
更新2
数据库中的TableA1,TableA2和TableB 已经存在,并具有以下结构:
CREATE TABLE TableA1 (
surrogate_key int AUTO_INCREMENT,
some_char char(30),
PRIMARY KEY (surrogate_key)
);
CREATE TABLE TableA2 (
surrogate_key int AUTO_INCREMENT,
some_int int,
PRIMARY KEY (surrogate_key)
);
CREATE TABLE TableB (
surrogate_key int AUTO_INCREMENT,
type int, // if type=1, sk represents the surrogate_key of tableA1
// if type=2, sk represents the surrogate_key of tableA2
sk int,
description varchar(200),
PRIMARY KEY (surrogate_key)
);
答案 0 :(得分:0)
更新回答:
已更新以匹配数据库
您可以使用getDiscriminatorValue()访问DiscriminatorValue。
定义这样的映射:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.INTEGER)
public abstract class TableA implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "surrogate_key")
protected int id;
@Id
@Column(name = "type")
protected int type;
// Constructors & getters/setters
@Transient
public String getDiscriminatorValue() {
DiscriminatorValue val = this.getClass().getAnnotation(DiscriminatorValue.class);
return val == null ? null : val.value();
}
}
@Entity
@DiscriminatorValue("1")
public class TableA1 extends TableA {
@Column(name = "some_char", length = 1)
private char someChar;
// Constructors & getters/setters & toString/equals
}
@Entity
@DiscriminatorValue("2")
public class TableA2 extends TableA {
@Column(name = "some_int")
private int someInt;
// Constructors & getters/setters & toString/equals
}
@Entity
public class TableB implements Serializable {
@Id
@GeneratedValue
@Column(name = "surrogate_key")
private int id;
@OneToOne
@Cascade(value = CascadeType.SAVE_UPDATE)
@JoinColumns({@JoinColumn(name = "sk", referencedColumnName = "surrogate_key"),
@JoinColumn(name = "type", referencedColumnName = "type")})
private TableA tableA;
@Column(name = "description", length = 200)
private String description;
// Constructors & getters/setters & toString/equals
}
并像这样查询:
newSession.createQuery("from TableB tb where tb.tableA.type=:type order by tb.id asc").setParameter("type", 1));