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