Back to list
psh-inc

jpa

by psh-inc

0🍴 0📅 Jan 24, 2026

SKILL.md


name: jpa description: | JPA entities, repositories, and Hibernate ORM patterns for Spring Boot 3.2.5 with Kotlin Use when: Creating/modifying entities, repositories, database queries, or handling persistence layer concerns allowed-tools: Read, Edit, Write, Glob, Grep, Bash

JPA Skill - Casino Platform

JPA/Hibernate patterns for the casino platform backend. This codebase uses Kotlin data classes with Spring Data JPA, PostgreSQL, and strict conventions for financial data handling.

Quick Start

Entity with ID and Auditing

@Entity
@Table(name = "transactions")
data class Transaction(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long? = null,

    @Column(nullable = false, precision = 19, scale = 4)
    val amount: BigDecimal,

    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    var status: TransactionStatus,

    @Column(name = "created_at", nullable = false)
    val createdAt: LocalDateTime = LocalDateTime.now(),

    @Column(name = "updated_at", nullable = false)
    var updatedAt: LocalDateTime = LocalDateTime.now(),

    @Version
    var version: Long = 0
)

Repository with JOIN FETCH

interface PlayerRepository : JpaRepository<Player, Long> {
    fun findByUsername(username: String): Optional<Player>

    @Query("""
        SELECT DISTINCT p FROM Player p
        LEFT JOIN FETCH p.wallet
        WHERE p.status = 'ACTIVE'
    """)
    fun findActivePlayersWithWallet(): List<Player>
}

Key Concepts

ConceptUsageExample
ID TypeAlways BIGSERIAL@GeneratedValue(strategy = GenerationType.IDENTITY)
MoneyBigDecimal from StringBigDecimal("123.45") not BigDecimal(123.45)
DatesLocalDateTime, UTCLocalDateTime.now(ZoneOffset.UTC)
EnumsSTRING not ORDINAL@Enumerated(EnumType.STRING)
LockingOptimistic@Version var version: Long = 0
Lazy LoadingDefault for relationsfetch = FetchType.LAZY

Common Patterns

Preventing N+1 Queries

When: Loading entities with their relationships

// BAD - N+1 queries
val players = repo.findByStatus(ACTIVE)
players.forEach { it.wallet?.balance }  // Separate query per player!

// GOOD - Single query with JOIN FETCH
@Query("SELECT p FROM Player p LEFT JOIN FETCH p.wallet WHERE p.status = 'ACTIVE'")
fun findActivePlayersWithWallet(): List<Player>

Bulk Updates with @Modifying

When: Updating multiple records without loading entities

@Modifying
@Query("""
    UPDATE Player p SET 
        p.status = :status, 
        p.updatedAt = CURRENT_TIMESTAMP 
    WHERE p.lastActivityAt < :threshold
""")
fun deactivateInactivePlayers(
    @Param("status") status: PlayerStatus,
    @Param("threshold") threshold: LocalDateTime
): Int

See Also

  • patterns - Entity, relationship, and query patterns
  • workflows - Common development workflows
  • See the spring-boot skill for service layer patterns and transactions
  • See the postgresql skill for Flyway migrations and database design
  • See the kotlin skill for Kotlin-specific JPA considerations

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon