@EmbeddedId 和 @GeneratedValue 在 @Embeddable [英] @EmbeddedId with @GeneratedValue in @Embeddable
问题描述
我有一个具有以下结构的 MySQL 数据库(摘录):
I have a MySQL DB with the following structure (excerpt):
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 表,但这并不重要,有了这些表,您就可以了解问题的全貌.
Also, there's a USER table but it's not important, with these you can have the full picture of the problem.
如您所见,某些列具有 AUTO_INCREMENT
属性,该属性将成为 @Entity
中的 @GeneratedValue(strategy = GenerationType.IDENTITY)
类.
As you can see, some columns has AUTO_INCREMENT
property which will become @GeneratedValue(strategy = GenerationType.IDENTITY)
in the @Entity
classes.
OPERATION
和 role_user
具有复合主键,因为它们与其他表的关系,所以我无法更改.由于复合PK
,映射的类必须有一个@EmbeddedId
和相应的@Embeddable
类.
OPERATION
and role_user
has composite primary keys because of the relation they have with the other tables, so I can't change that. Because of the composite PK
, the mapped classes must have an @EmbeddedId
with the corresponding @Embeddable
class.
问题是我需要在复合 PK
的 "native" 部分中有一个 @GeneratedValue
,例如:OPERATION.id_operation
必须有 @GeneratedValue
并且 OPERATION.id_menu
是从 MENU.id_menu 传播的,但是
JPA不支持
@GeneratedValuein
@EmbeddedId`.我是否正确地解释了情况?
The problem is that I need a @GeneratedValue
in the "native" part of the composite PK
, e.g.: OPERATION.id_operation
must have @GeneratedValue
and OPERATION.id_menu
is propagated from MENU.id_menu, but
JPAdoes not support
@GeneratedValuein
@EmbeddedId`. Am I explaining correctly the situation?
我尝试使用 NetBeans 的 suggestion" 的 Entity classes from DataBase 选项,但使用简单的表为表生成了 @GeneratedValue
注释列的标识符(如 MENU
)但不是组合的标识符(如 OPERATION
).
I tried with the NetBeans's "suggestion" of the Entity classes from DataBase option but generates the @GeneratedValue
annotation for the tables with simple column's identifier (like MENU
) but not for the composite's one (like OPERATION
).
所以问题是我该如何进行映射?.更改数据库的结构不是一种选择,而是出于业务需求才这样做的.
So the question is how can I do the mapping?. Changing the structure of the DB is not an option, it's made that way because of the business requirements.
感谢任何帮助或指导.在此先感谢您.
Any help or guide is appreciated. Thank you so much in advance.
推荐答案
您的 JPA @Id
不需要匹配数据库 PK 列.只要它是唯一的,那么这就是最重要的,并且由于关联的列是一个自动递增列,那么就是这种情况.
Your JPA @Id
does not need to match the database PK column(s). So long as it is unique then that is all that matters and as the associated column is an auto-increment column then this will be the case.
来自 https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing:
JPA Id 并不总是必须与数据库表主匹配键约束,也不需要主键或唯一约束.
The JPA Id does not always have to match the database table primary key constraint, nor is a primary key or a unique constraint required.
所以,虽然关联表的 PK 可以被配置为 PRIMARY KEY (id_operation, id_menu)
看起来,id_operation
,通过自动递增,可以作为PK独立,因此Operation可以映射如下:
So, while the PK for the associated table may be configured as PRIMARY KEY (id_operation, id_menu)
it would seem, id_operation
, through being auto-increment, could stand alone as a PK and therefore Operation can be mapped as below:
@Entity
public class Operation{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "id_menu")
private Menu menu;
}
如果您创建了相关的 IDClass,则 OperationRole 可以如下映射.有关此场景的示例以及 ID 类的外观,请参见:
If you create the relevant IDClass then OperationRole can be mapped as below. For an example of this scenario and how the ID class would loook see:
@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;
}
这篇关于@EmbeddedId 和 @GeneratedValue 在 @Embeddable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!