Generating UUIDs in Java
On this page
Java has had UUIDs in java.util.UUID since Java 5 (~2004). The standard library covers v3 and v4. For v7 (the modern default for primary keys), you need a third-party library — though several mature options exist.
The standard library
import java.util.UUID;
UUID id = UUID.randomUUID(); // v4 (random) — the default
String s = id.toString(); // canonical form
UUID parsed = UUID.fromString(s); // round-trip parse
java.util.UUID is a value type — immutable, hashable, comparable, and serializable. Its toString() always emits lowercase canonical form.
For deterministic UUIDs (v3):
String name = "https://example.com/users/42";
UUID v3 = UUID.nameUUIDFromBytes(name.getBytes(StandardCharsets.UTF_8));
This is v3 (MD5-based), not v5. The standard library does not provide a v5 generator.
v7 with uuid-creator
The most popular Java UUID library is uuid-creator by Fabio Lima. Add to your build.gradle:
implementation 'com.github.f4b6a3:uuid-creator:6.0.0'
Or pom.xml for Maven:
<dependency>
<groupId>com.github.f4b6a3</groupId>
<artifactId>uuid-creator</artifactId>
<version>6.0.0</version>
</dependency>
Then:
import com.github.f4b6a3.uuid.UuidCreator;
UUID v7 = UuidCreator.getTimeOrderedEpoch();
UUID v6 = UuidCreator.getTimeOrdered();
UUID v5 = UuidCreator.getNameBasedSha1(UuidNamespace.NAMESPACE_URL.getValue(),
"https://example.com");
uuid-creator handles same-millisecond monotonic sequencing, clock-rewind protection, and supports every variant in RFC 9562 — versions 1, 2, 3, 4, 5, 6, 7, 8.
JPA / Hibernate
Mapping a UUID column with JPA:
import jakarta.persistence.*;
import java.util.UUID;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
@Column(unique = true, nullable = false)
private String email;
}
GenerationType.UUID (added in Hibernate 6.2) generates v4 UUIDs in application code. For v7 you need a custom generator:
@Id
@GeneratedValue(generator = "uuidv7")
@GenericGenerator(name = "uuidv7",
strategy = "com.example.UuidV7Generator")
private UUID id;
Where UuidV7Generator calls UuidCreator.getTimeOrderedEpoch() and returns the result.
Spring Data JPA
public interface UserRepository extends JpaRepository<User, UUID> {
Optional<User> findByEmail(String email);
}
Spring auto-converts UUIDs in path variables and query parameters:
@GetMapping("/users/{id}")
public User getUser(@PathVariable UUID id) {
return repository.findById(id).orElseThrow();
}
Invalid UUIDs in the URL produce a 400 Bad Request before your handler runs.
Jackson serialization
java.util.UUID serializes to its canonical string by default — no configuration needed.
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(UUID.randomUUID());
// "0e6f1b8c-2c33-4f1f-9c0b-2a3d4e5f6a7b"
Bytes and the byte-order question
UUID id = UUID.randomUUID();
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(id.getMostSignificantBits());
bb.putLong(id.getLeastSignificantBits());
byte[] bytes = bb.array();
This produces RFC 4122 byte order (network / big-endian), which matches every non-Microsoft system. If you’re reading bytes from a SQL Server uniqueidentifier column extracted as raw bytes, byte-swap the first three groups — see UUID vs GUID.
Performance
UUID.randomUUID() is backed by a single global SecureRandom, which can become a contention point under high concurrency. For benchmarks:
| Approach | Throughput (single-threaded) |
|---|---|
UUID.randomUUID() | ~500K UUIDs/sec |
UuidCreator.getRandomBased() | ~1M UUIDs/sec |
UuidCreator.getTimeOrderedEpoch() | ~3M UUIDs/sec |
For a high-throughput service, prefer uuid-creator — it uses thread-local randomness and avoids the SecureRandom bottleneck.
Common pitfalls
UUID.fromStringdoesn’t validate strictly. It accepts some technically-invalid forms (e.g. lowercase variants of edge cases). For strict input validation, regex-check first.UUID.nameUUIDFromBytesis v3 (MD5), not v5 (SHA-1). The method name doesn’t say. If you need v5, useuuid-creator.- Hibernate’s
GenerationType.AUTOdoesn’t pick UUID even on UUID columns. Be explicit withGenerationType.UUID. - Don’t store UUIDs as
VARCHAR(36)in MySQL/PostgreSQL/SQL Server. Use the native UUID type — half the storage, faster joins.
Cheat sheet
| Goal | Code |
|---|---|
| Random UUID | UUID.randomUUID() |
| Time-ordered (v7) | UuidCreator.getTimeOrderedEpoch() |
| Name-based MD5 (v3) | UUID.nameUUIDFromBytes(name.getBytes(UTF_8)) |
| Name-based SHA-1 (v5) | UuidCreator.getNameBasedSha1(ns, name) |
| Parse | UUID.fromString(s) |
| Serialize bytes (RFC order) | ByteBuffer with putLong(msb) + putLong(lsb) |
Try the tools
- UUID generator — instant in-browser generation
- UUID v7 generator — modern primary keys
- UUID validator — paste any UUID, decode it
- UUID as primary key — Hibernate / JPA strategy