JPA - 实际主键生成的引用ID

时间:2012-12-11 10:54:56

标签: jpa eclipselink composite-primary-key

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

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

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

如果是,是否可以通过使用一些人工唯一密钥来引用它来避免它?你能否想一想在这种情况下需要如何描述真正的PK和人工PK?

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

问题#2: 所有10个类都有公共字段“date”,我在一个抽象类中描述了它们,每个类都扩展了。 “日期”本身永远不是关键,但它始终是每个类的复合键的一部分。每个类的复合键是不同的。 为了能够将此字段用作PK的一部分,我应该在每个类中描述它还是有任何方法可以按原样使用它? 我使用@Embedded和@PrimaryKey注释进行了实验,并且总是遇到一个错误,即eclipselink找不到抽象类中描述的字段。

提前谢谢!

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

2 个答案:

答案 0 :(得分:3)

我的建议:忘记功能性复合键:它们效率低下,使用起来很噩梦。只需为所有实体使用单列自动生成密钥。这也有利于使您的表更短更清洁(更少的列)。

这并不妨碍您在一组列上创建唯一约束,以确保例如只有一个记录带有a,b和c用于列col1,col2和col3。

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

select center from Center center 
where center.col1 = :col1 
and center.col2 = :col2
and center.col3 = :col3

答案 1 :(得分: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批注来简化指定复合键,您只需要提供列列表。您仍然必须将这些列映射到您班级中的属性。