@EmbeddedId 和 @GeneratedValue 在 @Embeddable [英] @EmbeddedId with @GeneratedValue in @Embeddable

查看:20
本文介绍了@EmbeddedId 和 @GeneratedValue 在 @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.

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

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 和 @GeneratedValue 在 @Embeddable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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