一尘不染

@Embeddable中具有@GeneratedValue的@EmbeddedId

hibernate

我有一个具有以下结构的MySQL数据库(节选):

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由于它们与其他表的关系而具有复合主键,因此我无法更改。由于为Composite
PK,因此映射的类必须具有一个@EmbeddedId带有相应@Embeddable类的。

问题是我需要@GeneratedValue在组合的 “本机”
部分中添加一个PK,例如:OPERATION.id_operation必须具有JPA @GeneratedValue @ EmbeddedId@GeneratedValueOPERATION.id_menu从中传播。我能正确解释情况吗?MENU.id_menu, butdoes not supportin`

我尝试使用NetBeans 从DataBase 选项的 Entity类“建议”
,但是为具有简单列的标识符(如)的表生成注释,而不为组合对象的表(如)生成注释。 __@GeneratedValue``MENU``OPERATION

所以问题是 我该如何进行映射? 。更改数据库的结构不是一种选择,因为业务需要,所以要这样做。

任何帮助或指导表示赞赏。提前非常感谢您。


阅读 348

收藏
2020-06-20

共1个答案

一尘不染

您的JPA @Id不需要匹配数据库PK列。只要它是唯一的,那么这就是所有要紧的事情,并且由于关联的列是自动递增的列,因此会是这种情况。

https://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing

JPA Id不必总是与数据库表的主键约束匹配,也不需要主键或唯一约束。

因此,尽管可以按照PRIMARY KEY (id_operation, id_menu)看起来的方式配置关联表的PK,但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类如何查找的示例,请参见:

https://zh.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;
}
2020-06-20