Kotlin Backend Jpa Entity Mapping
Model Kotlin persistence code correctly for Spring Data JPA and Hibernate.
Install
npx skills add Kotlin/kotlin-agent-skills --skill kotlin-backend-jpa-entity-mapping -g -a claude-code -y- Repository
- Kotlin/kotlin-agent-skills1.1k
- Category
- Design
- Updated
- 5d ago
- License
- Apache-2.0
- Context cost
- Mediumabout 1,696 tokens
- Runs scripts
- No, instructions only
What it does
Model Kotlin persistence code correctly for Spring Data JPA and Hibernate. Covers entity design, identity and equality, uniqueness constraints, relationships, fetch plans, and common ORM (Object-Relational Mapping) traps specific to Kotlin. Use when creating or reviewing JPA (Java Persistence API) entities, diagnosing N+1 or LazyInitializationException, placing indexes and uniqueness rules, or preventing Kotlin-specific bugs such as data class entities and broken equals/hashCode.
JPA Entity Mapping for Kotlin
Kotlin's data class is natural for DTOs but dangerous for JPA entities. Hibernate relies on
identity semantics that data class breaks: equals/hashCode over all fields corrupts
Set/Map membership after state changes, and auto-generated copy() creates detached
duplicates of managed entities.
This skill teaches correct entity design, identity strategies, and uniqueness constraints for Kotlin + Spring Data JPA projects.
Entity Design Rules
- Never use
data classfor JPA entities. Use a regularclass. Keepdata classfor DTOs. - Keep transport DTOs and persistence entities separate unless the project clearly uses a shared model.
- Model required columns as non-null only when object construction and persistence lifecycle make it safe.
- Use
lateinitonly when the project already accepts that tradeoff and the lifecycle is safe. - Verify
kotlin("plugin.jpa")or equivalent no-arg support when JPA entities exist. - Verify classes and members are compatible with proxying where needed.
Identity and Equality
- Never accept all-field
equals/hashCodegenerated bydata classon an entity. - Follow project conventions when they already define an identity strategy.
- If no convention exists, use ID-based equality with a stable
hashCode. - For DB-generated IDs, model the unsaved state with nullable
var id: Long? = nulland aprotected set; do not use0Las a sentinel value. - Be explicit about mutable fields and lazy associations when discussing equality.
Broken: data class Entity
// WRONG: data class generates equals/hashCode from ALL fields,
// and the generated ID uses a 0 sentinel instead of null
data class Order(
@Id @GeneratedValue val id: Long = 0,
var status: String,
var total: BigDecimal
)
// BUG: order.status = "SHIPPED"; set.contains(order) → false (hash changed)
// BUG: Hibernate proxy.equals(entity) → false (proxy has lazy fields uninitialized)


