idGenerators) {
+ this.idGenerators = idGenerators;
+ }
+
+ /**
+ * Register a customer IdGenerator instance.
+ */
+ public void add(IdGenerator idGenerator) {
+ idGenerators.add(idGenerator);
+ }
+
/**
* Register a BeanPersistController instance.
*
@@ -2277,7 +2297,7 @@ public class ServerConfig {
* @param instance existing instance
*/
@SuppressWarnings("unchecked")
- protected T createInstance(PropertiesWrapper properties, Class pluginType, String key, T instance) {
+ protected T createInstance(PropertiesWrapper properties, Class pluginType, String key, T instance) {
if (instance != null) {
return instance;
@@ -2288,8 +2308,9 @@ public class ServerConfig {
/**
* Return the instance to use (can be null) for the given plugin.
+ *
* @param pluginType the type of plugin
- * @param classname the implementation class as per properties
+ * @param classname the implementation class as per properties
*/
protected T createInstance(Class pluginType, String classname) {
return classname == null ? null : (T) classLoadConfig.newInstance(classname);
@@ -2362,7 +2383,7 @@ public class ServerConfig {
serverCacheManager = createInstance(p, ServerCacheManager.class, "serverCacheManager", serverCacheManager);
cacheWarmingDelay = p.getInt("cacheWarmingDelay", cacheWarmingDelay);
classPathReaderClassName = p.get("classpathreader");
-
+
String jarsProp = p.get("search.jars", p.get("jars", null));
if (jarsProp != null) {
searchJars = getSearchJarsPackages(jarsProp);
@@ -2378,7 +2399,7 @@ public class ServerConfig {
updateAllPropertiesInBatch = p.getBoolean("updateAllPropertiesInBatch", updateAllPropertiesInBatch);
updateChangesOnly = p.getBoolean("updateChangesOnly", updateChangesOnly);
-
+
boolean defaultDeleteMissingChildren = p.getBoolean("defaultDeleteMissingChildren", updatesDeleteMissingChildren);
updatesDeleteMissingChildren = p.getBoolean("updatesDeleteMissingChildren", defaultDeleteMissingChildren);
@@ -2442,10 +2463,8 @@ public class ServerConfig {
/**
* Build the list of classes from the comma delimited string.
- *
- * @param properties
- * the properties
- *
+ *
+ * @param properties the properties
* @return the classes
*/
private List> getClasses(PropertiesWrapper properties) {
@@ -2528,9 +2547,9 @@ public class ServerConfig {
/**
* Set to true if you want eq("someProperty", null) to generate "1=1" rather than "is null" sql expression.
*
- * Setting this to true has the effect that eq(propertyName, value), ieq(propertyName, value) and
- * ne(propertyName, value) have no effect when the value is null. The expression factory adds a NoopExpression
- * which will add "1=1" into the SQL rather than "is null".
+ * Setting this to true has the effect that eq(propertyName, value), ieq(propertyName, value) and
+ * ne(propertyName, value) have no effect when the value is null. The expression factory adds a NoopExpression
+ * which will add "1=1" into the SQL rather than "is null".
*
*/
public void setExpressionEqualsWithNullAsNoop(boolean expressionEqualsWithNullAsNoop) {
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java b/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java
index 3b6e40e7e..b8134c138 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/BootupClasses.java
@@ -1,6 +1,7 @@
package com.avaje.ebeaninternal.server.core;
import com.avaje.ebean.config.CompoundType;
+import com.avaje.ebean.config.IdGenerator;
import com.avaje.ebean.config.ScalarTypeConverter;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.event.BeanFindController;
@@ -48,6 +49,8 @@ public class BootupClasses implements ClassPathSearchMatcher, ClassFilter {
private final List> compoundTypeList = new ArrayList>();
+ private final List> idGeneratorList = new ArrayList>();
+
private final List> beanControllerList = new ArrayList>();
private final List> beanPostLoadList = new ArrayList>();
@@ -62,6 +65,7 @@ public class BootupClasses implements ClassPathSearchMatcher, ClassFilter {
private final List> serverConfigStartupList = new ArrayList>();
private final List serverConfigStartupInstances = new ArrayList();
+ private final List idGeneratorInstances = new ArrayList();
private final List findControllerInstances = new ArrayList();
private final List persistControllerInstances = new ArrayList();
private final List beanPostLoadInstances = new ArrayList();
@@ -116,6 +120,19 @@ public class BootupClasses implements ClassPathSearchMatcher, ClassFilter {
}
}
+ /**
+ * Add IdGenerator instances (registered explicitly with the ServerConfig).
+ */
+ public void addIdGenerators(List idGenerators) {
+ if (idGenerators != null) {
+ for (IdGenerator c : idGenerators) {
+ this.idGeneratorInstances.add(c);
+ // don't automatically instantiate
+ this.idGeneratorList.remove(c.getClass());
+ }
+ }
+ }
+
public void addQueryAdapters(List queryAdapterInstances) {
if (queryAdapterInstances != null) {
for (BeanQueryAdapter a : queryAdapterInstances) {
@@ -328,6 +345,13 @@ public class BootupClasses implements ClassPathSearchMatcher, ClassFilter {
return beanPostLoadInstances;
}
+ public List getIdGenerators() {
+ for (Class> cls : idGeneratorList) {
+ createAdd(cls, idGeneratorInstances);
+ }
+ return idGeneratorInstances;
+ }
+
public List getTransactionEventListeners() {
// add class registered TransactionEventListener to the already created instances
for (Class> cls : transactionEventListenerList) {
@@ -402,6 +426,11 @@ public class BootupClasses implements ClassPathSearchMatcher, ClassFilter {
}
boolean interesting = false;
+ if (IdGenerator.class.isAssignableFrom(cls)) {
+ idGeneratorList.add(cls);
+ interesting = true;
+ }
+
if (BeanPersistController.class.isAssignableFrom(cls)) {
beanControllerList.add(cls);
interesting = true;
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java
index d757568d2..284864e87 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/DefaultContainer.java
@@ -194,6 +194,7 @@ public class DefaultContainer implements SpiContainer {
private BootupClasses getBootupClasses(ServerConfig serverConfig) {
BootupClasses bootupClasses = getBootupClasses1(serverConfig);
+ bootupClasses.addIdGenerators(serverConfig.getIdGenerators());
bootupClasses.addPersistControllers(serverConfig.getPersistControllers());
bootupClasses.addPostLoaders(serverConfig.getPostLoaders());
bootupClasses.addFindControllers(serverConfig.getFindControllers());
diff --git a/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java b/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java
index 6cd87afd8..ed061bb83 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/core/InternalConfiguration.java
@@ -337,7 +337,7 @@ public class InternalConfiguration {
}
public GeneratedPropertyFactory getGeneratedPropertyFactory() {
- return new GeneratedPropertyFactory(serverConfig);
+ return new GeneratedPropertyFactory(serverConfig, bootupClasses.getIdGenerators());
}
/**
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java
index 51db0c4b7..75b859f29 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/BeanDescriptorManager.java
@@ -153,8 +153,6 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
private final DatabasePlatform databasePlatform;
- private final UuidIdGenerator uuidIdGenerator = new UuidIdGenerator();
-
private final ServerCacheManager cacheManager;
private final BackgroundExecutor backgroundExecutor;
@@ -1177,6 +1175,10 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
*/
private void setIdGeneration(DeployBeanDescriptor desc) {
+ if (desc.getIdGenerator() != null) {
+ // already assigned (So custom or UUID)
+ return;
+ }
if (desc.propertiesId().size() == 0) {
// bean doesn't have an Id property
if (desc.isBaseTableType() && desc.getBeanFinder() == null) {
@@ -1209,14 +1211,6 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
desc.setIdTypePlatformDefault();
}
- if (IdType.GENERATOR.equals(desc.getIdType())) {
- String genName = desc.getIdGeneratorName();
- if (UuidIdGenerator.AUTO_UUID.equals(genName)) {
- desc.setIdGenerator(uuidIdGenerator);
- return;
- }
- }
-
if (desc.getBaseTable() == null) {
// no base table so not going to set Identity
// of sequence information
@@ -1240,8 +1234,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
}
// create the sequence based IdGenerator
- PlatformIdGenerator seqIdGen = createSequenceIdGenerator(seqName);
- desc.setIdGenerator(seqIdGen);
+ desc.setIdGenerator(createSequenceIdGenerator(seqName));
}
private PlatformIdGenerator createSequenceIdGenerator(String seqName) {
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java
index 77cbceb02..890b6581f 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/generatedproperty/GeneratedPropertyFactory.java
@@ -1,12 +1,18 @@
package com.avaje.ebeaninternal.server.deploy.generatedproperty;
+import com.avaje.ebean.Transaction;
import com.avaje.ebean.config.ClassLoadConfig;
import com.avaje.ebean.config.CurrentUserProvider;
+import com.avaje.ebean.config.IdGenerator;
import com.avaje.ebean.config.ServerConfig;
+import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import java.math.BigDecimal;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
/**
* Default implementation of GeneratedPropertyFactory.
@@ -27,7 +33,9 @@ public class GeneratedPropertyFactory {
private final ClassLoadConfig classLoadConfig;
- public GeneratedPropertyFactory(ServerConfig serverConfig) {
+ private final Map idGeneratorMap = new HashMap();
+
+ public GeneratedPropertyFactory(ServerConfig serverConfig, List idGenerators) {
this.classLoadConfig = serverConfig.getClassLoadConfig();
this.insertFactory = new InsertTimestampFactory(classLoadConfig);
@@ -51,6 +59,12 @@ public class GeneratedPropertyFactory {
numberTypes.add(Double.class.getName());
numberTypes.add(double.class.getName());
numberTypes.add(BigDecimal.class.getName());
+
+ if (idGenerators != null) {
+ for (IdGenerator idGenerator : idGenerators) {
+ idGeneratorMap.put(idGenerator.getName(), new CustomIdGenerator(idGenerator));
+ }
+ }
}
public ClassLoadConfig getClassLoadConfig() {
@@ -98,4 +112,42 @@ public class GeneratedPropertyFactory {
property.setGeneratedProperty(generatedWhoModified);
}
+ /**
+ * Return the named custom IdGenerator (wrapped as a PlatformIdGenerator).
+ */
+ public PlatformIdGenerator getIdGenerator(String generatorName) {
+ return idGeneratorMap.get(generatorName);
+ }
+
+ /**
+ * Wraps the custom IdGenerator to implement PlatformIdGenerator.
+ */
+ private static class CustomIdGenerator implements PlatformIdGenerator {
+
+ private final IdGenerator generator;
+
+ CustomIdGenerator(IdGenerator generator) {
+ this.generator = generator;
+ }
+
+ @Override
+ public String getName() {
+ return generator.getName();
+ }
+
+ @Override
+ public boolean isDbSequence() {
+ return false;
+ }
+
+ @Override
+ public Object nextId(Transaction transaction) {
+ return generator.nextValue();
+ }
+
+ @Override
+ public void preAllocateIds(int allocateSize) {
+ // do nothing
+ }
+ }
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java
index 08c6504df..f4967557d 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/meta/DeployBeanDescriptor.java
@@ -29,6 +29,7 @@ import com.avaje.ebeaninternal.server.deploy.DeployNamedQuery;
import com.avaje.ebeaninternal.server.deploy.DeployNamedUpdate;
import com.avaje.ebeaninternal.server.deploy.InheritInfo;
import com.avaje.ebeaninternal.server.deploy.parse.DeployBeanInfo;
+import com.avaje.ebeaninternal.server.idgen.UuidIdGenerator;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;
@@ -830,6 +831,24 @@ public class DeployBeanDescriptor {
}
}
+ /**
+ * Assign the standard UUID generator.
+ */
+ public void setUuidGenerator() {
+ this.idType = IdType.EXTERNAL;
+ this.idGeneratorName = UuidIdGenerator.AUTO_UUID;
+ this.idGenerator = UuidIdGenerator.INSTANCE;
+ }
+
+ /**
+ * Assign a custom external IdGenerator.
+ */
+ public void setCustomIdGenerator(PlatformIdGenerator idGenerator) {
+ this.idType = IdType.EXTERNAL;
+ this.idGeneratorName = idGenerator.getName();
+ this.idGenerator = idGenerator;
+ }
+
/**
* Summary description.
*/
diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java
index 3d7a8cfd5..8b76eb7f6 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java
@@ -6,12 +6,12 @@ import com.avaje.ebean.config.EncryptDeploy.Mode;
import com.avaje.ebean.config.dbplatform.DbEncrypt;
import com.avaje.ebean.config.dbplatform.DbEncryptFunction;
import com.avaje.ebean.config.dbplatform.IdType;
+import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
import com.avaje.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssoc;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyCompound;
-import com.avaje.ebeaninternal.server.idgen.UuidIdGenerator;
import com.avaje.ebeaninternal.server.lib.util.StringHelper;
import com.avaje.ebeaninternal.server.type.CtCompoundType;
import com.avaje.ebeaninternal.server.type.DataEncryptSupport;
@@ -419,12 +419,8 @@ public class AnnotationFields extends AnnotationParser {
prop.setNullable(false);
if (prop.getPropertyType().equals(UUID.class)) {
- // An Id of type UUID
if (descriptor.getIdGeneratorName() == null) {
- // Without a generator explicitly specified
- // so will use the default one AUTO_UUID
- descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
- descriptor.setIdType(IdType.GENERATOR);
+ descriptor.setUuidGenerator();
}
}
}
@@ -449,14 +445,20 @@ public class AnnotationFields extends AnnotationParser {
} else if (strategy == GenerationType.SEQUENCE) {
descriptor.setIdType(IdType.SEQUENCE);
- if (genName != null && genName.length() > 0) {
+ if (!genName.equals("")) {
descriptor.setIdGeneratorName(genName);
}
} else if (strategy == GenerationType.AUTO) {
- if (prop.getPropertyType().equals(UUID.class)) {
- descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
- descriptor.setIdType(IdType.GENERATOR);
+ if (!genName.equals("")) {
+ // use a custom IdGenerator
+ PlatformIdGenerator idGenerator = generatedPropFactory.getIdGenerator(genName);
+ if (idGenerator == null) {
+ throw new IllegalStateException("No custom IdGenerator registered with name "+genName);
+ }
+ descriptor.setCustomIdGenerator(idGenerator);
+ } else if (prop.getPropertyType().equals(UUID.class)) {
+ descriptor.setUuidGenerator();
}
}
}
diff --git a/src/main/java/com/avaje/ebeaninternal/server/idgen/UuidIdGenerator.java b/src/main/java/com/avaje/ebeaninternal/server/idgen/UuidIdGenerator.java
index bd3070a76..58700925b 100644
--- a/src/main/java/com/avaje/ebeaninternal/server/idgen/UuidIdGenerator.java
+++ b/src/main/java/com/avaje/ebeaninternal/server/idgen/UuidIdGenerator.java
@@ -1,41 +1,43 @@
package com.avaje.ebeaninternal.server.idgen;
-import java.util.UUID;
-
import com.avaje.ebean.Transaction;
import com.avaje.ebean.config.dbplatform.PlatformIdGenerator;
+import java.util.UUID;
+
/**
* IdGenerator for java util UUID.
*/
public class UuidIdGenerator implements PlatformIdGenerator {
- /**
- * Return UUID from UUID.randomUUID();
- */
- public Object nextId(Transaction t) {
- return UUID.randomUUID();
- }
+ public static UuidIdGenerator INSTANCE = new UuidIdGenerator();
- /**
- * Returns "uuid".
- */
- public String getName() {
- return "uuid";
- }
+ /**
+ * Return UUID from UUID.randomUUID();
+ */
+ public Object nextId(Transaction t) {
+ return UUID.randomUUID();
+ }
- /**
- * Returns false.
- */
- public boolean isDbSequence() {
- return false;
- }
+ /**
+ * Returns "uuid".
+ */
+ public String getName() {
+ return "uuid";
+ }
- /**
- * Ignored for UUID as not required as a performance optimisation.
- */
- public void preAllocateIds(int allocateSize) {
- // ignored
- }
+ /**
+ * Returns false.
+ */
+ public boolean isDbSequence() {
+ return false;
+ }
+
+ /**
+ * Ignored for UUID as not required as a performance optimisation.
+ */
+ public void preAllocateIds(int allocateSize) {
+ // ignored
+ }
}
diff --git a/src/test/java/com/avaje/ebean/event/BeanFindControllerTest.java b/src/test/java/com/avaje/ebean/event/BeanFindControllerTest.java
index 0eaef65df..7476b7c22 100644
--- a/src/test/java/com/avaje/ebean/event/BeanFindControllerTest.java
+++ b/src/test/java/com/avaje/ebean/event/BeanFindControllerTest.java
@@ -7,12 +7,15 @@ import com.avaje.ebean.bean.BeanCollection;
import com.avaje.ebean.common.BeanList;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.tests.model.basic.EBasic;
+import com.avaje.tests.model.basic.ECustomId;
+import org.example.ModUuidGenerator;
import org.junit.Test;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class BeanFindControllerTest extends BaseTestCase {
@@ -30,7 +33,9 @@ public class BeanFindControllerTest extends BaseTestCase {
config.setDdlRun(true);
config.setRegister(false);
config.setDefaultServer(false);
+ config.add(new ModUuidGenerator());
config.getClasses().add(EBasic.class);
+ config.getClasses().add(ECustomId.class);
EBasicFindController findController = new EBasicFindController();
config.getFindControllers().add(findController);
@@ -61,6 +66,10 @@ public class BeanFindControllerTest extends BaseTestCase {
eBasic = list.get(0);
assertEquals(Integer.valueOf(47), eBasic.getId());
assertEquals("47", eBasic.getName());
+
+ ECustomId bean = new ECustomId("check");
+ ebeanServer.save(bean);
+ assertNotNull(bean.getId());
}
static class EBasicFindController implements BeanFindController {
diff --git a/src/test/java/com/avaje/tests/idkeys/TestCustomId.java b/src/test/java/com/avaje/tests/idkeys/TestCustomId.java
new file mode 100644
index 000000000..f98e9b1fb
--- /dev/null
+++ b/src/test/java/com/avaje/tests/idkeys/TestCustomId.java
@@ -0,0 +1,33 @@
+package com.avaje.tests.idkeys;
+
+import com.avaje.ebean.BaseTestCase;
+import com.avaje.ebean.Ebean;
+import com.avaje.tests.model.basic.ECustomId;
+import org.avaje.moduuid.ModUUID;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestCustomId extends BaseTestCase {
+
+ @Test
+ public void insert() {
+
+ ECustomId bean = new ECustomId("fred");
+ Ebean.save(bean);
+ assertNotNull(bean.getId());
+ }
+
+ @Test
+ public void insert_when_hasValue() {
+
+ ECustomId bean = new ECustomId("gotId");
+ String explicitId = ModUUID.newShortId();
+ bean.setId(explicitId);
+ Ebean.save(bean);
+
+ ECustomId found = Ebean.find(ECustomId.class, explicitId);
+ assertEquals(found.getName(), bean.getName());
+ }
+}
diff --git a/src/test/java/com/avaje/tests/model/basic/ECustomId.java b/src/test/java/com/avaje/tests/model/basic/ECustomId.java
new file mode 100644
index 000000000..0bd0cb2dc
--- /dev/null
+++ b/src/test/java/com/avaje/tests/model/basic/ECustomId.java
@@ -0,0 +1,34 @@
+package com.avaje.tests.model.basic;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+@Entity
+public class ECustomId {
+
+ @Id @GeneratedValue(generator = "shortUid")
+ String id;
+
+ String name;
+
+ public ECustomId(String name) {
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/test/java/org/example/ModUuidGenerator.java b/src/test/java/org/example/ModUuidGenerator.java
new file mode 100644
index 000000000..b34b26b61
--- /dev/null
+++ b/src/test/java/org/example/ModUuidGenerator.java
@@ -0,0 +1,20 @@
+package org.example;
+
+import com.avaje.ebean.config.IdGenerator;
+import org.avaje.moduuid.ModUUID;
+
+/**
+ * A customer Id Generator that can be assigned by @GeneratedValue(generator="shortUid")
+ */
+public class ModUuidGenerator implements IdGenerator {
+
+ @Override
+ public Object nextValue() {
+ return ModUUID.newShortId();
+ }
+
+ @Override
+ public String getName() {
+ return "shortUid";
+ }
+}