
kotlin-backend-jpa-entity-mapping
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.
- Installs
- 1.6K
- Last 24h
- +12
- Trending rank
- #7802
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/kotlin/kotlin-agent-skills --skill kotlin-backend-jpa-entity-mapping- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads kotlin-backend-jpa-entity-mapping automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
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)
Correct: Regular Class with ID-Based Identity
@Entity
@Table(name = "orders")
class Order(
@Column(nullable = false)
var status: String,
@Column(nullable = false)
var total: BigDecimal
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null
protected set
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Order) return false
return id != null && id == other.id
}
override fun hashCode(): Int = javaClass.hashCode()
// toString must NOT reference lazy collections
override fun toString(): String = "Order(id=$id, status=$status)"
}
Key rules:
equalscompares by ID only — stable under dirty tracking and proxy unwrappinghashCodereturns class-based constant — avoidsSet/Mapcorruption after persisttoStringexcludes lazy-loaded relations — preventsLazyInitializationException- Constructor params are mutable entity fields; DB-generated
idis nullable with a protected setter
Uniqueness Constraints
When an API must be idempotent (e.g., "reserve stock for order X"), enforce uniqueness at both layers: database constraint for correctness, application check for clean errors.
Broken: No Duplicate Guard
@Service
class ReservationService(private val repo: ReservationRepository) {
@Transactional
fun createReservation(variantId: Long, orderId: String, qty: Int): Reservation {
// BUG: no check — duplicates silently accumulate
return repo.save(Reservation(variantId = variantId, orderId = orderId, quantity = qty))
}
}
Correct: Database Constraint + Application Guard
@Entity
@Table(
name = "reservations",
uniqueConstraints = [
UniqueConstraint(columnNames = ["variant_id", "order_id"])
]
)
class Reservation(
@Column(name = "variant_id", nullable = false)
val variantId: Long,
@Column(name = "order_id", nullable = false)
val orderId: String,
@Column(nullable = false)
var quantity: Int
) {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null
protected set
}
interface ReservationRepository : JpaRepository<Reservation, Long> {
fun findByVariantIdAndOrderId(variantId: Long, orderId: String): Reservation?
}
@Service
class ReservationService(private val repo: ReservationRepository) {
@Transactional
fun createReservation(variantId: Long, orderId: String, qty: Int): Reservation {
repo.findByVariantIdAndOrderId(variantId, orderId)?.let {
throw IllegalStateException(
"Reservation already exists for variant=$variantId, order=$orderId"
)
}
return repo.save(Reservation(variantId = variantId, orderId = orderId, quantity = qty))
}
}
Key rules:
- Database constraint is mandatory — application checks alone have race conditions
- Application check provides clean error messages — without it, users get raw
DataIntegrityViolationException - Both layers together: application catches the common case, database catches the race
- Spring Data derives
findByXAndYqueries automatically
Query and Fetch Rules
- Diagnose N+1 by looking at actual query count or SQL logs, not by guessing from annotations.
- Prefer targeted fetch solutions:
@EntityGraph,JOIN FETCH, batch fetching, or DTO projection. - Be careful with collection fetch joins plus pagination — call out the tradeoff.
- Use indexes and uniqueness constraints to support real query patterns.
Common ORM Traps
- Bidirectional associations: maintain both sides in domain methods. Half-updated graphs cause subtle bugs.
orphanRemovalvs cascade remove: not interchangeable. Explain lifecycle semantics before choosing.- Lazy load triggers:
toString, debug logging, JSON serialization, and IDE inspection can all trigger lazy loads. - Bulk updates/deletes: bypass persistence context and lifecycle callbacks. Subsequent reads may be stale.
- Multiple bag fetches: can cause Cartesian explosion. Verify the ORM can execute collection-heavy fetch plans safely.
Set+ mutable equality: collection membership can break after entity state changes.@Version: the clearest optimistic concurrency mechanism when concurrent updates matter.open-in-viewdisabled: DTO mapping touching lazy fields must happen inside a transaction boundary.
Guardrails
- Do not use
data classfor JPA entities. - Do not recommend
FetchType.EAGEReverywhere to silence lazy loading symptoms. - Do not expose entities directly through API responses by default.
- Do not claim an N+1 fix without explaining how the fetch plan changes query behavior.
FAQ
What does the kotlin-backend-jpa-entity-mapping skill do?
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.
How do I install kotlin-backend-jpa-entity-mapping?
Run npx skills add https://github.com/kotlin/kotlin-agent-skills --skill kotlin-backend-jpa-entity-mapping in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/kotlin-backend-jpa-entity-mapping/ (personal) or .claude/skills/kotlin-backend-jpa-entity-mapping/ (project).
Which AI agents can use kotlin-backend-jpa-entity-mapping?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is kotlin-backend-jpa-entity-mapping safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains kotlin-backend-jpa-entity-mapping?
It is published by kotlin in kotlin/kotlin-agent-skills, and it is an official skill from the maker of the technology it covers. It has 1,601 recorded installs.
More from kotlin/kotlin-agent-skills
kotlin-tooling-agp9-migration
kotlin/kotlin-agent-skills
Migrates Kotlin Multiplatform (KMP) projects to Android Gradle Plugin 9.0+. Handles plugin replacement (com.android.kotlin.multiplatform.library), module splitting, DSL migration, and the new default project structure. Use when upgrading AGP, when build fails due to KMP+AGP incompatibility, or when the user mentions AGP 9.0, android multiplatform plugin, KMP migration, or com.android.kotlin.multiplatform.library.
kotlin-tooling-java-to-kotlin
kotlin/kotlin-agent-skills
Use when converting Java source files to idiomatic Kotlin, when user mentions "java to kotlin", "j2k", "convert java", "migrate java to kotlin", or when working with .java files that need to become .kt files. Handles framework-aware conversion for Spring, Lombok, Hibernate, Jackson, Micronaut, Quarkus, Dagger/Hilt, RxJava, JUnit, Guice, Retrofit, and Mockito.
kotlin-tooling-cocoapods-spm-migration
kotlin/kotlin-agent-skills
Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(), transforms cocoapods. imports to swiftPMImport., and reconfigures the Xcode project.
kotlin-tooling-immutable-collections-0-5-x-migration
kotlin/kotlin-agent-skills
Migrate Kotlin (and Java) code from kotlinx.collections.immutable 0.3.x / 0.4.x to the latest 0.5.x. The 0.5.x line renames every copy-returning method on PersistentList / PersistentMap / PersistentSet / PersistentCollection to a participial form per KEEP-0459 (add→adding, removeAt→removingAt, set→replacingAt, put→putting, clear→cleared, …) and deprecates the old names (WARNING, with ReplaceWith). Driven by the compiler: bump the version, recompile, and apply the rename each deprecation warning names. Use when the user mentions kotlinx.collections.immutable 0.5.x, PersistentList migration, "Use adding() instead", KEEP-0459, or sees deprecation warnings from kotlinx.collections.immutable.
kotlin-tooling-native-build-performance
kotlin/kotlin-agent-skills
Diagnoses and fixes slow Kotlin/Native compilation and linking in Kotlin Multiplatform projects that target iOS. Use when the user reports slow iOS or shared-framework builds, long linkDebug/linkRelease or XCFramework tasks, cold CI builds that re-download the Kotlin/Native toolchain, KSP or other generated code on the native path, transitiveExport usage, or asks for a local-development versus CI build performance plan.
kotlin-tooling-kotlin-toolchain
kotlin/kotlin-agent-skills
Open the skill to read its SKILL.md instructions.
Popular mobile skills
design-mobile-apps
designed-by-ai/skills
Design mobile app screens with Sleek, edit Sleek projects, and implement their designs in React Native or HTML.
ios-design
uizze.sh
Design and review iOS UI/UX for iPhone apps in SwiftUI, UIKit, or React Native. Use for mobile app design, screen redesigns, navigation flows, typography, forms, keyboard and safe-area layout, and accessibility checks. Apply Apple Human Interface Guidelines and consult real product references through the optional Uizze connection.
vercel-react-native-skills
vercel-labs/agent-skills
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
animate-expo
emilkowalski/skills
Build animations in React Native and Expo, making the decisions in the order that determines whether they feel right — should it animate, which thread it runs on, which properties, spring or timing, how the gesture hands off, how it degrades. Writes the implementation with Reanimated, Gesture Handler, Expo Router and expo-haptics. Use when animating anything in an Expo app, adding gestures, sheets, screen transitions, press feedback or haptics, or fixing motion that stutters on device. For web animation use animate.
xcode-project-setup
firebase/agent-skills
Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
firebase-remote-config-basics
firebase/agent-skills
Manages Firebase Remote Config templates, feature flags, loading strategies, and SDKs (Android, iOS). Use when downloading/deploying remoteconfig JSON templates, managing version history/feature flags, setting in-app defaults, fetchAndActivate(), real-time listeners, or SDK setup. Don't use for Firebase Hosting, Auth, Firestore, Data Connect, Crashlytics, or App Hosting.