@EmbeddedId @Embeddable中的@GeneratedValue [英] @EmbeddedId with @GeneratedValue in @Embeddable
问题描述
我有一个具有以下结构的MySQL数据库(摘录):
pre $ 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,
角色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)
);
- 关系
-
- TABLE:OPERATION
- 含义:一个MENU有几个操作(一对多关系)
ALTER TABLE OPERACION ADD CONSTRAINT fk_menu_operacion
FOREIGN KEY(id_menu)
REFERENCES MENU(id_menu);
-
- TABLE:operation_rol
- 这是多对多关系的连接表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);
$ b -
- TABLE:roles_usuario
- 含义:用户可以有多个角色(一对多)
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
以及相应的 @可嵌入的类。
问题是我需要 @GeneratedValue
em>native部分组合 PK
,例如: OPERATION.id_operation
必须包含<$从 MENU.id_menu传播c $ c> @GeneratedValue
和 OPERATION.id_menu
,但是 JPA 不支持
@GeneratedValue 在
@ EmbeddedId`中。我是否正确地解释了这种情况?
我尝试了NetBeans的建议来自DataBase的实体类选项,但为具有简单列标识符的表(如 MENU
)生成 @GeneratedValue
注释,但不为组合的(比如 OPERATION
)。
所以问题是我该如何做映射?。更改数据库的结构不是一种选择,因为业务需求而变化。
任何帮助或指南都是值得赞赏的。提前感谢你。
您的JPA @Id
确实不需要匹配数据库PK列。只要它是唯一的,那么这就是所有重要的,因为相关的列是一个自动增量列,那么情况就是这样。
From https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing :
JPA标识并不总是与数据库表primary
键约束匹配,也不需要主键或唯一约束。
因此,虽然关联表的PK可以配置为 PRIMARY KEY(id_operation,id_menu)
看起来, id_operation
,通过自动增量,可以独立作为PK,因此Operation可以如下映射:
@Entity
public class Operation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
私人长ID;
@ManyToOne
@JoinColumn(name =id_menu)
私人菜单菜单;
$ b如果你创建相关的IDClass,那么OperationRole可以如下映射。对于这个场景的一个例子以及ID类如何可以看到:
<$ p $
@IdClass(OperationRolePk.class)
public class OperationRole {
@Id
@ManyToOne
@ JoinColumn(name =id_operation)
私有操作操作;
@Id
@ManyToOne
@JoinColumn(name =id_menu)
私人菜单菜单;
@Id
@ManyToOne
@JoinColumn(name =id_user)
私人用户用户;
}
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);
Also, there's a USER table but it's not important, with these you can have the full picture of the problem.
As you can see, some columns has AUTO_INCREMENT
property which will become @GeneratedValue(strategy = GenerationType.IDENTITY)
in the @Entity
classes.
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.
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?
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.
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.
From https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing:
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.
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;
}
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 @Embeddable中的@GeneratedValue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!