我有一个具有以下结构的MySQL数据库(节选):
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将@GeneratedValue(strategy = GenerationType.IDENTITY)在@Entity类中变为的属性。
AUTO_INCREMENT
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Entity
OPERATION并且role_user由于它们与其他表的关系而具有复合主键,因此我无法更改。由于为Composite PK,因此映射的类必须具有一个@EmbeddedId带有相应@Embeddable类的。
OPERATION
role_user
PK
@EmbeddedId
@Embeddable
问题是我需要@GeneratedValue在组合的 “本机” 部分中添加一个PK,例如:OPERATION.id_operation必须具有JPA @GeneratedValue @ EmbeddedId@GeneratedValue并OPERATION.id_menu从中传播。我能正确解释情况吗?MENU.id_menu, butdoes not supportin`
@GeneratedValue
OPERATION.id_operation
并
从中传播。我能正确解释情况吗?
does not support
我尝试使用NetBeans 从DataBase 选项的 Entity类 的 “建议” ,但是为具有简单列的标识符(如)的表生成注释,而不为组合对象的表(如)生成注释。 __@GeneratedValue``MENU``OPERATION
@GeneratedValue``MENU``OPERATION
所以问题是 我该如何进行映射? 。更改数据库的结构不是一种选择,因为业务需要,所以要这样做。
任何帮助或指导表示赞赏。提前非常感谢您。
您的JPA @Id不需要匹配数据库PK列。只要它是唯一的,那么这就是所有要紧的事情,并且由于关联的列是自动递增的列,因此会是这种情况。
@Id
从https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing:
JPA Id不必总是与数据库表的主键约束匹配,也不需要主键或唯一约束。
因此,尽管可以按照PRIMARY KEY (id_operation, id_menu)看起来的方式配置关联表的PK,但id_operation通过自动递增,它可以单独作为PK,因此可以将操作映射如下:
PRIMARY KEY (id_operation, id_menu)
id_operation
@Entity public class Operation{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "id_menu") private Menu menu; }
如果创建相关的IDClass,则可以如下映射OperationRole。有关此方案以及ID类如何查找的示例,请参见:
https://zh.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; }