【发布时间】:2016-07-20 05:01:36
【问题描述】:
我试图弄清楚如何构建 JPA 实体 bean 以使数据适用于我的设备。数据库很旧而且一成不变,所以我无法更改架构。 Device Models 有一个复合主键,其中一列是 Device Type 的 FK。
我尝试了几种不同的方法。首先是 Device 有一个 DeviceModel 和一个 DeviceType,但这给了我一个错误,即有太多东西引用了 dev_type。于是我尝试让 DeviceModel 引用 DeviceType 但我遇到了同样的错误。
如果有帮助/重要,我将使用 Spring Data 4.2.x 和 Hibernate 4.3.8.Final 来支持一切。
我在网上找到的其他答案(例如How to create and handle composite primary key in JPA)对我没有帮助,因为它们只映射到基本数据类型。其实上面的答案是在我下面的代码中实现的……不过我还需要再上一层。
架构:
create table devices
(
device_nbr serial(1),
device_id nchar(20) not null unique,
dev_type integer not null,
model_nbr integer default 1,
unit_addr nchar(32),
primary key (device_nbr),
foreign key (dev_type) references devtypes (dev_type),
foreign key (dev_type, model_nbr) references devmodels (dev_type, model_nbr)
);
create table devmodels
(
dev_type integer not null,
model_nbr integer not null,
model_desc nchar(20),
primary key (dev_type, model_nbr),
foreign key (dev_type) references devtypes (dev_type)
);
create table devtypes
(
dev_type integer not null,
dev_desc nchar(16) not null unique,
primary key (dev_type)
);
到目前为止我的 Beans(它没有将 DeviceType 与 Device 或 DeviceModel 联系起来,这就是我需要帮助的地方):
@Entity
@Table(name = "devices")
public class Device
{
@Id
@GeneratedValue
@Column(name = "device_nbr")
private Long number;
@Column(name = "device_id", length = 30)
private String id;
@Column(name = "unit_addr", length = 30)
private String unitAddress;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumns({
@JoinColumn(name = "dev_type"),
@JoinColumn(name = "model_nbr")
})
private DeviceModel deviceModel;
...Getters and setters
}
public class DeviceModelPK implements Serializable
{
private static final long serialVersionUID = -8173857210615808268L;
protected Integer deviceTypeNumber;
protected Integer modelNumber;
...Getters and setters
}
@Entity
@Table(name = "devmodels")
@IdClass(DeviceModelPK.class)
public class DeviceModel
{
@Id
@Column(name = "dev_type")
private Integer deviceTypeNumber;
@Id
@Column(name = "model_nbr")
private Integer modelNumber;
@Column(name = "model_desc")
private String description;
...Getters and setters
}
@Entity
@Table(name = "devtypes")
public class DeviceType
{
@Id
@GeneratedValue
@Column(name = "dev_type")
private Integer number;
@Column(name = "dev_desc", length = 30)
private String description;
...Getters and setters
}
【问题讨论】:
-
为什么不试试
@EmbeddedId而不是@IdClass?as they only map to basic data types你找到相关的参考了吗? -
虽然我还没有尝试过使用
@EmbeddedId,但我看不出它将如何解决引用同一列的 2 个不同 java 字段的问题。 -
我没有发现任何问题。你有一个设备类型,它有自己的 id。然后你有属于类型的模型,每个模型都有一个数字和类型 id,它是一个外键,两列都构成复合主键。即使将
DeviceModelPK中的两个字段都设为 int,您也不应该有任何问题。