我有一个具有以下结构的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
属性在@GeneratedValue(strategy = GenerationType.IDENTITY)
类中将变为@Entity
。
OPERATION
和role_user
具有复合主键,因为它们与其他表有关系,所以我无法改变它。由于复合PK
,映射的类必须具有@EmbeddedId
和相应的@Embeddable
类。
问题是我在复合@GeneratedValue
的“native”部分需要PK
,例如:OPERATION.id_operation
必须@GeneratedValue
}和OPERATION.id_menu
是从MENU.id_menu, but
JPA does not support
@ GeneratedValue in
@ EmbeddedId`传播的。我能正确解释一下情况吗?
我尝试使用来自DataBase 选项的实体类的NetBeans的“建议”,但为具有简单列标识符的表生成@GeneratedValue
注释(如MENU
)但不适用于复合的一个(如OPERATION
)。
所以问题是我该如何进行映射?。更改数据库的结构不是一种选择,因为业务需求,它就是这样做的。
感谢任何帮助或指南。非常感谢你。
答案 0 :(得分:3)
您的JPA @Id
不需要与数据库PK列匹配。只要它是唯一的那么重要的是,因为相关的列是一个自动增量列,那么情况就是这样。
来自https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing:
JPA Id并不总是必须匹配数据库表primary 密钥约束,也不是主键或唯一约束。
因此,虽然关联表的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类将如何处理,请参阅:
@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;
}