kotlin-tooling-agp9-mi…
Migrates Kotlin Multiplatform (KMP) projects to Android Gradle Plugin 9.0+. Handles plugin replacement (com.android.kotlin.multiplatform.library), module…
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
$ npx -y skills add kotlin/kotlin-agent-skills --skill kotlin-backend-jpa-entity-mapping --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/kotlin-backend-jpa-entity-mappingContext preview
The summary Claude sees to decide when to auto-load this skill.
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
name: kotlin-backend-jpa-entity-mapping description: > 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. license: Apache-2.0 metadata: author: JetBrains version: "1.0.0"
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.
and a `protected set`; do not use `0L` as a sentinel value.
// 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)@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:**
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.
@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))
}
}@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:**
A collection of AI agent skills useful for projects using the Kotlin language. Skills are following the Agent Skills standard, see agentskills.io for more information.
Migrates Kotlin Multiplatform (KMP) projects to Android Gradle Plugin 9.0+. Handles plugin replacement (com.android.kotlin.multiplatform.library), module…
Migrate KMP projects from CocoaPods (kotlin("native.cocoapods")) to Swift Package Manager (swiftPMDependencies DSL) — replaces pod() with swiftPackage(),…
Load when porting, converting, or reimplementing a single Gradle plugin as a Kotlin Toolchain local plugin, or when mapping Gradle plugin concepts (Task,…
Load when migrating or converting an entire Gradle Kotlin project (build.gradle(.kts), wrapper, libs.versions.toml, buildSrc) to the Kotlin Toolchain,…
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…
Use when converting Java source files to idiomatic Kotlin, when user mentions "java to kotlin", "j2k", "convert java", "migrate java to kotlin", or when…