@EmbeddedId @Embeddable中的@GeneratedValue [英] @EmbeddedId with @GeneratedValue in @Embeddable

查看:118
本文介绍了@EmbeddedId @Embeddable中的@GeneratedValue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下结构的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 AD​​D 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类如何可以看到:


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



<$ 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, butJPAdoes 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:

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;
}

这篇关于@EmbeddedId @Embeddable中的@GeneratedValue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆