【发布时间】:2014-02-26 00:28:16
【问题描述】:
我正在处理无法更改的旧数据库。该数据库定期与创建新条目的辅助实例同步。为了使实体的主键对所有实例都是唯一的,所有实体都具有复合主键,其中包括由其原始数据库生成的代理键和标识原始实例的服务器 ID。
复合主键对于 Hibernate / JPA 来说是没有问题的,它看起来像这样:
@Embeddable
public class ID implements Serializable {
private Long autoin; // Surrogate key
private Integer serverId; // instance identifier
@Column(name = "autoin_fix")
public Long getAutoin() {
return this.autoin;
}
@Column(name = "servdat_fk")
public Integer getServerId() {
return this.serverId;
}
// ... setter, equals, hashCode ...
}
现在考虑以下实体:
@Entity
@Table(name = "LEADS")
public class Request {
private Long id;
private Article article;
private Location location;
@Id
@Column(name = "autoin_fix")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto-increment")
@GenericGenerator(name = "auto-increment", strategy = "sequence",
parameters = @org.hibernate.annotations.Parameter(name = "sequence", value = "AUTOINCREMENT"))
public Long getId() {
return this.id;
}
@ManyToOne
@JoinColumns({
@JoinColumn(name = "artikel_fk", referencedColumnName = "autoin_fix",
insertable = false, updatable = false), // Here is the problem!
@JoinColumn(name = "servdat_fk", referencedColumnName = "servdat_fk",
insertable = false, updatable = false)
})
public Article getArticle() {
return this.article;
}
@ManyToOne
@JoinColumns({
@JoinColumn(name = "standort_fk", referencedColumnName = "autoin_fix"),
@JoinColumn(name = "servdat_fk", referencedColumnName = "servdat_fk")
})
public Location getLocation() {
return this.location;
}
// Setters omitted
}
Request 实体引用了另外两个实体,它们都使用复合主键来标识自己。但由于从业务逻辑的角度来看,这两个实体(文章和位置)的 serverId总是必须相同,因此数据库中的 serverId 只有一列:
TABLE leads
-------------
autoin_fix
artikel_fk
standort_fk
servdat_fk // This only exists once, but is part of the association to both Article and Location!
为了让应用程序完全启动,我必须将 insertable = false, updatable = false 添加到 Article 关联中,这不是我想要的。如果我尝试持久化 Request 对象,则不会写入字段“artikel_fk”,在数据库中留下空值,因为我告诉 hibernate 它是只读的。并且只允许在其中一个连接列上使用 insertable = false, updatable = false。
// This is illegal and the application won't start
@JoinColumns({
@JoinColumn(name = "artikel_fk", referencedColumnName = "autoin_fix"),
@JoinColumn(name = "servdat_fk", referencedColumnName = "servdat_fk", insertable = false, updatable = false)
})
有人知道这个问题的解决方案吗?或者这不可能使用 Hibernate / JPA 进行映射?
编辑:文章和位置的(简化)定义(真的没那么有趣,重要的是它们使用复合主键):
@Entity
@Table(name = "ARTIKEL")
public class Article {
private ID id;
private String headline;
private String description;
@EmbeddedId
public ID getId() {
return this.id;
}
@Column(name = "artbesch")
public String getDescription() {
return this.description;
}
@Column(name = "artueschr")
public String getHeadline() {
return this.headline;
}
// Setters omitted
}
@Entity
@Table(name = "STANDORT")
public class Location {
private ID id;
private GeoCoordinates geoCoordinates;
private Name name;
@EmbeddedId
public ID getId() {
return this.id;
}
@Embedded
public GeoCoordinates getGeoCoordinates() {
return this.geoCoordinates;
}
@Embedded
public Name getName() {
return this.name;
}
// Setters omitted
}
【问题讨论】:
-
您能按照我们的方式发布文章和位置的定义吗?
标签: java hibernate jpa orm jpa-2.0