Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when generating a JPA/Hibernate entity with a UUID primary key (and/or a UUID or String @ElementCollection): use the current Hibernate 6 + Jakarta Persistence annotations, not the deprecated Hibernate 5 idiom cheaper models default to.
.claude/skills/hibernate6-uuid-entity-mapping/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 4 |
| Model | Lift | Δ tokens | Δ turns | Cases | Verified |
|---|---|---|---|---|---|
| gemini-3.6-flashbest | +41% | +66% | 0% | 22 | 54d ago |
| gemini-3.5-flash | pending re-run | — | |||
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-18 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-04 | ✗→✓ | ▲ Improved | — | — |
| case-03 | ✗→✓ | ▲ Improved | — | — |
Enforces the current way to map a UUID-identified JPA/Hibernate entity, as defined by Hibernate ORM 6 and Jakarta Persistence 3.1. Apply whenever you generate an @Entity whose identifier is a java.util.UUID (especially a random / RFC 4122 version-4 id) or that stores a collection of scalar values with @ElementCollection. The base model reaches for the Hibernate 5 recipe by default; this skill pins the Hibernate 6 / Jakarta tokens instead.
jakarta.persistence, never javax.persistence. Since Jakarta EE 9 / JPA 3.0 everypersistence annotation moved packages: jakarta.persistence.Entity, jakarta.persistence.Id, jakarta.persistence.GeneratedValue, jakarta.persistence.Column, jakarta.persistence.Table, jakarta.persistence.ElementCollection, jakarta.persistence.CollectionTable, jakarta.persistence.JoinColumn. Hibernate 6 requires this namespace.
java.util.UUID. Never a Long/Integer auto-increment, never a String.Do not fall back to @GeneratedValue(strategy = GenerationType.IDENTITY).
@UuidGenerator, not the legacy @GenericGenerator. The idcarries @Id, @GeneratedValue, and @UuidGenerator (from org.hibernate.annotations). Do NOT use the removed Hibernate 5 string-strategy form: @GeneratedValue(generator = "uuid4") + @GenericGenerator(name = "uuid4", strategy = "org.hibernate.id.UUIDGenerator").
@UuidGenerator(style = UuidGenerator.Style.RANDOM). Style.RANDOM maps toUUID.randomUUID() — an RFC 4122 version-4 value. Style.TIME is time-based (not version 4); Style.AUTO is the default and behaves as RANDOM. When the requirement says "version 4" or "random", write style = UuidGenerator.Style.RANDOM explicitly.
@Type. Hibernate 6.0 removed @Type(type = "..."); the type string attributeno longer exists. A java.util.UUID maps natively with NO @Type at all. Never write @Type(type = "org.hibernate.type.UUIDCharType"), uuid-char, pg-uuid, or uuid2. Drop columnDefinition = "uuid" unless you deliberately want a vendor-specific DDL type.
@ElementCollection is configured with @CollectionTable + @JoinColumn + @Column. A collectionof scalars (e.g. List<UUID> or List<String>) uses @ElementCollection, then @CollectionTable(name = "...", joinColumns = @JoinColumn(name = "...")) to name the side table and its foreign key, then @Column(name = "...") for the value column. Collection elements are supplied by the application and mapped natively — do not attach @UuidGenerator, @GenericGenerator, or a String @Type to them.
Primary key — legacy default → current form.
java// BEFORE (Hibernate 5 idiom the base emits by default): import javax.persistence.*; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Type; @Id @GeneratedValue(generator = "uuid4") @GenericGenerator(name = "uuid4", strategy = "org.hibernate.id.UUIDGenerator") @Type(type = "org.hibernate.type.UUIDCharType") @Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false) private UUID id; // AFTER (Hibernate 6 + Jakarta): import jakarta.persistence.*; import org.hibernate.annotations.UuidGenerator; import java.util.UUID; @Id @GeneratedValue @UuidGenerator(style = UuidGenerator.Style.RANDOM) @Column(name = "id", updatable = false, nullable = false) private UUID id;
javax → jakarta; the @GenericGenerator string strategy and the String @Type are gone; the random (version-4) style is declared with @UuidGenerator(style = UuidGenerator.Style.RANDOM).
Element collection of UUIDs — legacy default → current form.
java// BEFORE: @ElementCollection @CollectionTable(name = "dog_attribute", joinColumns = @JoinColumn(name = "dog_id")) @Column(name = "attribute", columnDefinition = "uuid") @Type(type = "org.hibernate.type.UUIDCharType") private List<UUID> attributes; // AFTER: @ElementCollection @CollectionTable(name = "dog_attribute", joinColumns = @JoinColumn(name = "dog_id")) @Column(name = "attribute") private List<UUID> attributes;
The side table + foreign-key column stay; the removed String @Type and the unneeded columnDefinition drop away — List<UUID> maps natively in Hibernate 6.
@UuidGenerator(style = UuidGenerator.Style.RANDOM)(RFC 4122 version 4) — it is the modern default and matches UUID.randomUUID().
@GeneratedValue(strategy = GenerationType.UUID) (Jakarta Persistence 3.1) isalso valid, but the JPA spec does not guarantee a specific UUID version. When the task explicitly wants version 4, prefer Hibernate's @UuidGenerator(style = Style.RANDOM), which does.
@Id and theUUID type and simply omit @GeneratedValue/@UuidGenerator.
uuid column. You may add @JdbcTypeCode(SqlTypes.UUID) if you need to force thenative SQL type; this replaces the old columnDefinition = "uuid" / pg-uuid hacks. Still no String @Type.
Set instead of List. Set<UUID> / Set<String> collections use the exact same@ElementCollection + @CollectionTable + @JoinColumn + @Column annotations.
javax.persistence.*. ALWAYS import jakarta.persistence.*.@GeneratedValue(generator = "uuid4") + @GenericGenerator(strategy = "org.hibernate.id.UUIDGenerator").ALWAYS use @UuidGenerator.
@Type(type = "org.hibernate.type.UUIDCharType") (or any @Type(type = "...")). ALWAYS letjava.util.UUID map natively.
Long, Integer, or String. ALWAYS type it java.util.UUID.style = UuidGenerator.Style.RANDOM.
@CollectionTable/@JoinColumn from an @ElementCollection. ALWAYS name the side table andits foreign key.
javax.persistence, @GenericGenerator, and @Type(type = "...").@GeneratedValue(strategy = GenerationType.AUTO) and hoping for a UUID instead of declaring@UuidGenerator.
columnDefinition = "uuid" plus a String @Type, which no longer compiles under Hibernate 6.style = UuidGenerator.Style.RANDOM when version 4 is explicitly required.@Type as if they were generated identifiers.jakarta.persistence.* (not javax.persistence.*).java.util.UUID.@Id + @GeneratedValue + @UuidGenerator (no @GenericGenerator string strategy).@UuidGenerator(style = UuidGenerator.Style.RANDOM) when version 4 / random is wanted.@Type(type = "...") anywhere; UUID maps natively.@ElementCollection has @CollectionTable(joinColumns = @JoinColumn(...)) + @Column.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.5-flash | verified | 7/10/2026 | +67% |
Other measured skills in the registry, with their headline benchmark lift.