0

我有大约 10 个类,每个类都有复合键,由 2-4 个值组成。其中 1 个类是主要类(我们称其为“中心”),并且与其他类以一对一或一对多的方式相关。

考虑在 JPA 中描述这一点的正确方法,我认为我需要使用 @Embedded / @PrimaryKey 注释来描述所有主键。

问题#1: 我担心的是——这是否意味着在数据库级别上,每个表中引用“中心”的附加列数等于“中心”PK 中的列数?

如果是,是否可以通过使用一些人为的唯一键进行引用来避免它?你能告诉我在这种情况下如何描述真实的PK和人工的PK吗?

注意:我想保留真正的 PK 而不仅仅是像 PK 那样使用唯一 id 的原因是 - 我的应用程序具有一些来自外部数据源的数据加载功能,有时它们可​​能会返回我已经在本地数据库中拥有的记录。如果将唯一 ID 用作 PK - 对于新记录,我将无法进行数据更新,因为唯一 ID 不适用于刚刚下载的记录。同时这是应用程序的正常情况,它只需要更新插入新记录,这取决于真正的复合主键是否匹配。

问题 #2: 所有 10 个类都有公共字段“日期”,我在一个抽象类中对其进行了描述,每个类都扩展了该字段。“日期”本身从来都不是键,但它始终是每个类的组合键的一部分。每个类的复合键都不同。为了能够将此字段用作 PK 的一部分,我应该在每个类中描述它还是有什么方法可以按原样使用它?我尝试了@Embedded 和@PrimaryKey 注释,总是得到一个错误,即eclipselink 找不到抽象类中描述的字段。

先感谢您!

PS。我正在使用最新版本的 eclipselink & H2 数据库。

4

2 回答 2

3

我的建议:忘记功能组合键:它们效率低下,而且使用起来简直就是一场噩梦。只需为所有实体使用单列自动生成的键。这也将具有使您的表格更短和更清洁(更少的列)的优势。

这并不妨碍您在一组列上创建唯一约束,以确保例如,对于列 col1、col2 和 col3,只有一条包含 a、b 和 c 的记录。

如果您想检查 a、b、c 的记录是否已经存在,只需创建一个查询:

select center from Center center 
where center.col1 = :col1 
and center.col2 = :col2
and center.col3 = :col3
于 2012-12-11T11:02:21.817 回答
1

看,

http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Composite_Primary_Keys

有关复合键的信息。

通常使用单个生成的 id 更好,但如果您有旧数据,则可以使用复合键。

我不建议使用@EmbeddedId,而是使用@IdClass,它更简单。EclipseLink 不需要@IdClass,但如果您希望使用 find(),那么您需要一个来组合键值。

您应该能够使用 @MappedSuperclass 来定义其中一个 id 字段,确保您使用 @Id 注释每个关键字段。

EclipseLink 确实允许使用 @PrimaryKey 注释来简化指定复合键,您只需要提供列列表。您仍然必须将这些列映射到您的类中的属性。

于 2012-12-11T15:17:05.450 回答