@EmbeddedId与@Gembeddable中的@GeneratedValue

我有一个具有以下结构的MySQL DB(摘录):

CREATE TABLE MENU( id_menu TINYINT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, PRIMARY KEY (id_menu) ); CREATE TABLE OPERATION( id_operation SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, id_menu TINYINT UNSIGNED NOT NULL, operation VARCHAR(50) NOT NULL, url VARCHAR(100) NOT NULL, PRIMARY KEY (id_operation, id_menu) ); CREATE TABLE operation_role( id_operation SMALLINT UNSIGNED NOT NULL, id_menu TINYINT UNSIGNED NOT NULL, role CHAR(15) NOT NULL, id_user BIGINT UNSIGNED NOT NULL, PRIMARY KEY (id_operation, id_menu, role, id_user) ); CREATE TABLE role_user( role CHAR(15) NOT NULL id_user BIGINT UNSIGNED NOT NULL, PRIMARY KEY (role, id_user) ); -- RELATIONSHIPS -- -- TABLE: OPERATION -- Meaning: a MENU has several OPERATION (One to Many relationship) ALTER TABLE OPERACION ADD CONSTRAINT fk_menu_operacion FOREIGN KEY (id_menu) REFERENCES MENU(id_menu); -- -- TABLE: operation_rol -- This is the join table for the Many to Many relatioship OPERATION-role_user ALTER TABLE operation_role ADD CONSTRAINT fk_operation_oprole FOREIGN KEY (id_operation, id_menu) REFERENCES OPERATION(id_operation, id_menu); ALTER TABLE operaciones_rol ADD CONSTRAINT fk_roles_operation FOREIGN KEY (role, id_user) REFERENCES role_user(role, id_user); -- -- TABLE: roles_usuario -- Meaning: a user can have several roles (One to Many) ALTER TABLE roles_usuario ADD CONSTRAINT fk_usuario_roles FOREIGN KEY (id_usuario) REFERENCES USUARIO(id_usuario); 

此外,还有一个USER表,但这并不重要,通过这些表可以全面了解问题。

如您所见,某些列具有AUTO_INCREMENT属性,该属性将成为@Entity类中的@GeneratedValue(strategy = GenerationType.IDENTITY)

OPERATIONrole_user具有复合主键,因为它们与其他表有关系,因此我无法更改它。 由于复合PK ,映射的类必须具有@EmbeddedId和相应的@Embeddable类。

问题是我在复合PK“原生”部分需要一个@GeneratedValue ,例如: OPERATION.id_operation必须有@GeneratedValueOPERATION.id_menu是从MENU.id_menu, but传播的MENU.id_menu, but JPA does not support @EmbeddedId中的@GeneratedValue `。 我能正确解释这种情况吗?

我尝试使用NetBeans对DataBase选项中的Entity类“建议” ,但为具有简单列标识符(如MENU )的表生成@GeneratedValue注释,但不为复合的类(如OPERATION )生成。

所以问题是如何进行映射? 。 更改数据库的结构不是一种选择,因为业务需求,它就是这样做的。

任何帮助或指南表示赞赏。 非常感谢你提前。

您的JPA @Id不需要匹配数据库PK列。 只要它是唯一的,那就重要了,因为相关的列是一个自动增量列,那么情况就是如此。

来自https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing :

JPA Id并不总是必须匹配数据库表主键约束,也不需要主键或唯一约束。

因此,虽然关联表的PK可以配置为PRIMARY KEY (id_operation, id_menu) ,但看起来, id_operation通过自动递增,可以单独作为PK,因此可以如下映射操作:

 @Entity public class Operation{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "id_menu") private Menu menu; } 

如果您创建相关的IDClass,则可以如下映射OperationRole。 有关此方案的示例以及ID类如何处理,请参阅:

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Example_JPA_2.0_ManyToOne_id_annotation

 @Entity @IdClass(OperationRolePk.class) public class OperationRole{ @Id @ManyToOne @JoinColumn(name = "id_operation") private Operation operation; @Id @ManyToOne @JoinColumn(name = "id_menu") private Menu menu; @Id @ManyToOne @JoinColumn(name = "id_user") private User user; }