【问题标题】:Changing hibernate generator value from increment to native将休眠生成器值从增量更改为本机
【发布时间】:2020-03-06 23:27:07
【问题描述】:

问题: 我将 1 个服务器、1 个 db 设置扩展为 2 个服务器 1 个 db 设置。我作为 ORM 运行 Spring boot 和休眠。当前每个表都带有注释:

@Id
@GeneratedValue(generator = "increment")
@GenericGenerator(name = "increment", strategy = "increment")
@Column(name = "id")

而 ddl 的示例可能是这样的:

create table drugs

(id                 bigint               not null
    primary key, ....)

这会在运行 2 个服务器时出现刷新错误,因为每个应用服务器只会在初始化时检查当前索引,然后盲目地增加 id。

我目前的做法: 为了避免这种情况,我希望数据库设置键并休眠以实现“本机”策略,因此向所有就绪的现有主键添加一个自动增量。

问题是每个表都有多个外键约束。所以我尝试了To add Auto increment while running SET FOREIGN KEY CHECK = 0

LOCK TABLES
drugs WRITE;
SET FOREIGN_KEY_CHECKS = 0;
ALTER table drugs DROP PRIMARY KEY;
ALTER TABLE drugs MODIFY id bigint PRIMARY KEY AUTO_INCREMENT NOT NULL ;

SET FOREIGN_KEY_CHECKS = 1;
UNLOCK TABLES ;

但得到错误

(errno: 150 "外键约束格式不正确")

我愿意接受其他想法来解决这个问题或解决我的问题的方法:)

【问题讨论】:

  • 首先什么是数据库版本?因为如果您可以将序列与 mariadb 10.3 方言一起使用,那么使用与原生不同的解决方案会更好
  • “原生”PK 是什么?您在此表中还有其他带有FOREIGN KEYs 的表吗?反之亦然?
  • 我使用 MariaDB v. 10.2。我有很多表需要执行相同的过程,其中很多表都有外键约束。谢谢你们。

标签: mysql sql hibernate mariadb


【解决方案1】:

解决了这个问题。我最终完成了一个 5 步程序:

  1. 保存给定主键的每个外键约束
  2. 移除上述限制
  3. 删除主键
  4. 应用主键和自动增量
  5. 再次应用每个外键
CREATE OR REPLACE PROCEDURE alter_primary_key(P_SCHEMA VARCHAR(64), P_TABLE VARCHAR(64), P_COLUMN VARCHAR(64)) MODIFIES SQL DATA
BEGIN
    DECLARE V_CONSTRAINT_SCHEMA VARCHAR(64);
    DECLARE V_TABLE_NAME VARCHAR(64);
    DECLARE V_CONSTRAINT_NAME VARCHAR(64);
    DECLARE V_COLUMN_NAME VARCHAR(64);
    DECLARE V_REFERENCED_TABLE_SCHEMA VARCHAR(64);
    DECLARE V_REFERENCED_TABLE_NAME VARCHAR(64);
    DECLARE V_REFERENCED_COLUMN_NAME VARCHAR(64);
    DECLARE C CURSOR FOR SELECT CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM foreign_keys;

    CREATE OR REPLACE TEMPORARY TABLE magi.foreign_keys (CONSTRAINT_SCHEMA VARCHAR(64), TABLE_NAME VARCHAR(64), CONSTRAINT_NAME VARCHAR(64), COLUMN_NAME VARCHAR(64), REFERENCED_TABLE_SCHEMA VARCHAR(64), REFERENCED_TABLE_NAME VARCHAR(64), REFERENCED_COLUMN_NAME VARCHAR(64));
    INSERT INTO magi.foreign_keys (CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME)
    SELECT CONSTRAINT_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_SCHEMA, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE
    WHERE REFERENCED_TABLE_SCHEMA = P_SCHEMA AND REFERENCED_TABLE_NAME = P_TABLE AND REFERENCED_COLUMN_NAME = P_COLUMN;


    OPEN C;
    BEGIN
        DECLARE done INT DEFAULT FALSE;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
        read_loop: LOOP
            FETCH C INTO V_CONSTRAINT_SCHEMA, V_TABLE_NAME, V_CONSTRAINT_NAME, V_COLUMN_NAME, V_REFERENCED_TABLE_SCHEMA, V_REFERENCED_TABLE_NAME, V_REFERENCED_COLUMN_NAME;
            IF done THEN
                LEAVE read_loop;
            END IF;
            SET @STMT = CONCAT('ALTER TABLE ', V_CONSTRAINT_SCHEMA, '.', V_TABLE_NAME, ' DROP FOREIGN KEY ', V_CONSTRAINT_NAME);
            PREPARE STMT FROM @STMT;
            EXECUTE STMT;
        END LOOP;
    END;
    CLOSE C;


    SET @STMT = CONCAT('ALTER TABLE ' , P_SCHEMA , '.' , P_TABLE , ' DROP PRIMARY KEY');
    PREPARE STMT FROM @STMT;
    EXECUTE STMT;

#     SET @STMT = CONCAT('ALTER TABLE ' , P_SCHEMA , '.' , P_TABLE , ' MODIFY COLUMN ' , P_COLUMN , ' bigint AUTO_INCREMENT NOT NULL PRIMARY KEY');
    SET @STMT = CONCAT('ALTER TABLE ' , P_SCHEMA , '.' , P_TABLE , ' MODIFY COLUMN ', P_COLUMN ,' bigint AUTO_INCREMENT PRIMARY KEY');
    PREPARE STMT FROM @STMT;
    EXECUTE STMT;


    OPEN C;
        BEGIN
        DECLARE done INT DEFAULT FALSE;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
        read_loop2: LOOP
            FETCH C INTO V_CONSTRAINT_SCHEMA, V_TABLE_NAME, V_CONSTRAINT_NAME, V_COLUMN_NAME, V_REFERENCED_TABLE_SCHEMA, V_REFERENCED_TABLE_NAME, V_REFERENCED_COLUMN_NAME;
            IF done THEN
                LEAVE read_loop2;
            END IF;
            SET @STMT = CONCAT('ALTER TABLE ',V_CONSTRAINT_SCHEMA,'.',V_TABLE_NAME,' ADD CONSTRAINT ',V_CONSTRAINT_NAME,' FOREIGN KEY (',V_COLUMN_NAME,') REFERENCES ' , V_REFERENCED_TABLE_SCHEMA , '.' , V_REFERENCED_TABLE_NAME,' (',V_REFERENCED_COLUMN_NAME,')');
            PREPARE STMT FROM @STMT;
            EXECUTE STMT;
        END LOOP;
    END;
    CLOSE C;

END

CALL alter_primary_key('mydatabase', 'mytable', 'id');

【讨论】:

    猜你喜欢
    • 2011-10-10
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多