Try it here
Generate a UUID to paste into your Java code, in any version and format.
Your UUIDs
Copy one, copy them all, or download the list. The format options above apply to everything shown here.
The standard library: randomUUID
import java.util.UUID;
UUID id = UUID.randomUUID(); // version 4, from SecureRandom
String s = id.toString(); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
id.version(); // 4
java.util.UUID has been in the JDK since Java 5. randomUUID uses a SecureRandom instance, so the values are safe to use anywhere a v4 UUID is appropriate.
Time ordered v7
The JDK does not generate v7 yet. Two well maintained libraries do.
// uuid-creator
// implementation 'com.github.f4b6a3:uuid-creator:<latest>'
import com.github.f4b6a3.uuid.UuidCreator;
UUID id = UuidCreator.getTimeOrderedEpoch(); // v7
// java-uuid-generator
// implementation 'com.fasterxml.uuid:java-uuid-generator:<latest>'
import com.fasterxml.uuid.Generators;
UUID id = Generators.timeBasedEpochGenerator().generate(); // v7
Either library also gives you v1, v5 and v6. Use v7 for entity ids so inserts append to the end of the index. The v7 page has the reasoning.
Name based UUIDs
// standard library, this is version 3 (MD5) and takes raw bytes, no namespace
UUID id = UUID.nameUUIDFromBytes("example.com".getBytes(StandardCharsets.UTF_8));
// RFC style v5 with a namespace, via uuid-creator
UUID id = UuidCreator.getNameBasedSha1(UuidNamespace.NAMESPACE_DNS, "example.com");
Note the difference. nameUUIDFromBytes hashes only the bytes you give it, so its output will not match Python's uuid3(NAMESPACE_DNS, name) or our v3 generator, which follow the RFC and hash the namespace first.
Parse and validate
UUID u = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
// fromString is lenient: this parses without error on many JDKs
UUID.fromString("1-2-3-4-5"); // 00000001-0002-0003-0004-000000000005
// so validate the shape first when the input is untrusted
private static final Pattern UUID_RE =
Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$");
boolean ok = UUID_RE.matcher(input).matches();
JPA and Hibernate
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.UUID) // Hibernate 6.2+, JPA 3.1
private UUID id;
}
// or assign it yourself, which lets you pick v7
@Id
private UUID id = UuidCreator.getTimeOrderedEpoch();
Hibernate 6 maps UUID to the native uuid type on PostgreSQL and to BINARY(16) on MySQL by default. Older setups that stored CHAR(36) work but use more than twice the space and index memory.
Mistakes to avoid
- Trusting fromString as validation. It accepts inputs that are not RFC UUIDs. Check with a regex when the value comes from outside.
- Assuming nameUUIDFromBytes is v5. It is v3 without a namespace.
- Calling new Random for ids. randomUUID already uses SecureRandom. Do not build ids from java.util.Random.
Frequently asked questions
Is UUID.randomUUID() thread safe?
Yes. It creates values from a shared SecureRandom in a way that is safe to call from any thread, and it is fast enough for most workloads.
How do I generate a UUID v7 in Java?
Use uuid-creator's UuidCreator.getTimeOrderedEpoch() or java-uuid-generator's Generators.timeBasedEpochGenerator().generate(). The JDK has no built in v7.
Should I store UUIDs as CHAR(36) or BINARY(16) in MySQL?
BINARY(16). It is 16 bytes instead of 36, indexes are smaller and comparisons faster. Hibernate 6 does this by default.