Skip to content

Add setting to customize primary key type used for models

Anton Sudak requested to merge a.sudak/play-cms:uuid-as-primary-key into master

This pull request introduces new setting key for Play CMS that allows to customize primary key type for Model classes.

cms.commons.primaryKeyType = "uuid" # acceptable values are "uuid" and "orm-default"

  • uuid - used by default - set uuid as a primary key for all entities inherited from Model
  • orm-default - set ORM default primary key type (usually auto-increment) for all entities inherited from Model

To work with this feature persistence.xml in existing projects should be updated with the new property:

<property name="eclipselink.session.customizer" value="ch.insign.commons.db.PrimaryKeyCustomizer"/>

This property could be set on project level only and is required for proper play-cms work.

NOTE: this change will break existing code! id field of Model class now have String type instead of long and this potentially will break existing code.

If you are going to switch to uuid db schema changes will be required as well. In most scenarios, migrating script could be prepared by using following SQL:

-- Change database_schema value to corresponding database name
SET @database_schema = 'app';

-- We need to recreate foreign keys because InnoDB doesn't allow difference in column types even if foreign_key_checks is set to 0

SELECT
 CONCAT('ALTER TABLE ', table_name, ' DROP FOREIGN KEY ', constraint_name, ';') 
FROM 
 information_schema.key_column_usage 
WHERE
 table_schema = @database_schema AND
 referenced_table_schema = @database_schema AND
 referenced_column_name = 'ID';

SELECT
 CONCAT('ALTER TABLE ', table_name, ' MODIFY COLUMN ', column_name, ' char(36) NOT NULL;') 
FROM
 information_schema.columns 
WHERE 
 column_name = 'ID' AND 
 table_schema = @database_schema;

SELECT
 CONCAT('ALTER TABLE ', cu.table_name, ' MODIFY COLUMN ', cu.column_name, ' char(36) ', CASE c.is_nullable WHEN 'no' THEN 'NOT NULL' WHEN 'YES' THEN '' END, ';')
FROM 
 information_schema.key_column_usage cu JOIN information_schema.columns c ON cu.table_name = c.table_name AND cu.column_name = c.column_name
WHERE
 cu.table_schema = @database_schema AND 
 cu.referenced_table_schema = @database_schema AND 
 cu.referenced_column_name = 'ID';

SELECT
 CONCAT('ALTER TABLE ', table_name, ' ADD FOREIGN KEY ', constraint_name, ' (', column_name, ')', ' REFERENCES ', referenced_table_name,'(', referenced_column_name, ');')
FROM
 information_schema.key_column_usage
WHERE
 table_schema = @database_schema AND 
 referenced_table_schema = @database_schema AND 
 referenced_column_name = 'ID';

Also note, that DefaultParty and DefaultPartyRole classes now inherit Model in order to keep primary keys consistent all over the project.

Edited by Anton Sudak

Merge request reports