Skip to content

TSID Support

TSID (Time-Sorted Unique Identifier) combines the best of auto-increment and UUID: 64-bit, roughly time-ordered (index friendly!), cluster-safe and rendered as a compact 13-character Crockford base-32 string like 0GWVCNQ9WM7ST. commons-rest-tsid makes TSID a first-class citizen in your REST layer.

<dependency>
<groupId>io.rocketbase.commons</groupId>
<artifactId>commons-rest-tsid</artifactId>
<version>4.0.0-M2</version>
</dependency>
<dependency>
<groupId>io.hypersistence</groupId>
<artifactId>hypersistence-tsid</artifactId>
<version>2.1.4</version>
</dependency>

The auto-configuration registers a Jackson module (TSID ↔ string), a Spring MVC formatter for TSID parameters and an exception handler mapping invalid ids to 404.

TSID id = TSID.Factory.getTsid(); // generate
String text = id.toString(); // "0GWVCNQ9WM7ST"
long value = id.toLong(); // 64-bit representation for the database

DTO fields serialize to the canonical string automatically:

public class LocationRead {
private TSID id; // → "id": "0GWVCNQ9WM7ST"
private String name;
}

Path variables bind directly — invalid input raises TsidDecodeException404:

@GetMapping("/api/location/{id}")
public LocationRead getById(@PathVariable TSID id) {
return converter.fromEntity(repository.findById(id.toLong())
.orElseThrow(NotFoundException::new));
}

Pairs nicely with hypersistence-utils@Tsid generator — store a Long, expose a TSID:

@Entity
public class LocationEntity {
@Id @Tsid
private Long id;
private String name;
}
// converter
LocationRead.builder()
.id(TSID.from(entity.getId()))
.name(entity.getName())
.build();
Property Default Explanation
tsid.handler.enabled true toggle the 404 handler for TsidDecodeException

Node bits, custom epoch and generation tuning are configured through the hypersistence-tsid library itself (system properties / environment) — see its documentation.

TSID ObfuscatedId
id source generated (time-sorted) existing numeric ids
hides count/growth ✔ (timestamp-based) ✔ (hashed)
sortable by creation
works with auto-increment ✘ (new id strategy) ✔ (wraps existing Long)

Use TSID for new schemas; use hashids to retrofit privacy onto existing sequential ids.