Manually specify the value of a primary key in JPA @GeneratedValue column

后端 未结 6 1151
眼角桃花
眼角桃花 2020-12-29 02:42

I\'m having an Entity which has a primary key / id field like the following:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
         


        
6条回答
  •  长情又很酷
    2020-12-29 02:58

    Database-centric solution to your problem:

    1. Create an auxiliary, nullable column in your table. It will hold your manually assigned ids:

      CREATE TABLE `test_table`
      (
        `id` bigint(20) NOT NULL AUTO_INCREMENT,
        `manual_id` bigint(20) NULL,
        `some_other_field` varchar(200) NOT NULL,
        PRIMARY KEY(id)
      );
      
    2. Map this column to a normal field in your Entity:

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      @Column(name="manual_id")
      private Integer manualId;
      
    3. Create a trigger that sets the table id to the manual assigned id if it is not null:

      DELIMITER //
      CREATE TRIGGER `test_table_bi` BEFORE INSERT ON `test_table`
        FOR EACH ROW 
        BEGIN
          IF NEW.`manual_id` IS NOT NULL THEN 
            SET NEW.`id` = NEW.`manual_id`;
          END IF;
      END;//
      DELIMITER;    
      
    4. Always use the manualId when you need to assign a custom id. The trigger will do the magic for you:

      testEntiy.setManualId(300);
      entityManager.persist(testEntity);
      
    5. After the database import phase, simple remove the trigger, the auxiliary column and it's mapping.

      DROP TRIGGER `test_table_bi`;
      ALTER TABLE `test_table` DROP COLUMN `manual_id`;
      

    Warning

    If you manually specify an id greater than the current AUTO_INCREMENT value, the next generated id will jump to the value of the manually assigned id plus 1, e.g.:

    INSERT INTO `test_table` (manual_id, some_other_field) VALUES (50, 'Something');
    INSERT INTO `test_table` (manual_id, some_other_field) VALUES (NULL, 'Something else');
    INSERT INTO `test_table` (manual_id, some_other_field) VALUES (90, 'Something 2');
    INSERT INTO `test_table` (manual_id, some_other_field) VALUES (NULL, 'Something else 2');
    INSERT INTO `test_table` (manual_id, some_other_field) VALUES (40, 'Something 3');
    INSERT INTO `test_table` (manual_id, some_other_field) VALUES (NULL, 'Something else 3');
    

    Will wield the results:

    +----+-----------+------------------+
    | id | manual_id | some_other_field |
    +----+-----------+------------------+
    | 50 |        50 | Something        |
    | 51 |      NULL | Something else   |
    | 90 |        90 | Something 2      |
    | 91 |      NULL | Something else 2 |
    | 40 |        40 | Something 3      |
    | 92 |      NULL | Something else 3 |
    +----+-----------+------------------+
    

    To avoid problems it is highly recommended to set the AUTO_INCREMENT column to start with a number greater than all of the existing ids in your previous database, e.g.:

    ALTER TABLE `test_table` AUTO_INCREMENT = 100000;
    

提交回复
热议问题