Mysql

80 posts in this section

One-to-Many and Many-to-One: The Most Common Relationship

Introduction The one-to-many relationship is the most common in any domain model. An Order has many OrderItems. A Category has many Products. A Customer has many Orders. Understanding @OneToMany and @ManyToOne well — especially bidirectional mapping, collection types, and cascade configuration — is foundational to any JPA application. The Domain Example orders (1) ──────────────── (*) order_items An order has many order items. Each order item belongs to exactly one order.

Continue reading »

One-to-One Relationships: @OneToOne in Depth

Introduction A one-to-one relationship means one record in table A corresponds to exactly one record in table B. In JPA this is modelled with @OneToOne. Understanding where the foreign key lives, which side “owns” the relationship, and how cascade operations work is essential before moving to the more complex @OneToMany and @ManyToMany. The Domain Example In the e-commerce system, a Customer has one CustomerProfile containing their preferences and biography. A profile belongs to exactly one customer.

Continue reading »

Optimistic and Pessimistic Locking: Handling Concurrent Updates

The Lost Update Problem Two users edit the same product simultaneously: Time User A User B T1 Load product (price=999) Load product (price=999) T2 Change price to 899 T3 Change price to 799 T4 Save → UPDATE price=899 T5 Save → UPDATE price=799 User A’s change is silently overwritten. This is the lost update problem. Both JPA locking strategies prevent it — in different ways. Optimistic Locking with @Version Optimistic locking assumes conflicts are rare.

Continue reading »

Pagination and Sorting with Pageable, Page, and Slice

Why Pagination Matters Returning all rows from a database table is one of the most common production incidents. A query that works in development with 100 rows silently becomes a 10-second, 2 GB memory spike when production has 2 million rows. Pagination limits how many rows travel from the database to the application at a time. Spring Data JPA makes pagination a first-class feature — pass a Pageable to any repository method and get a Page<T> back.

Continue reading »

Partitioning: Splitting Work Across Parallel Workers

Introduction Multi-threaded steps (Article 20) run multiple chunks concurrently from a single reader. Partitioning is different — it splits the data into independent slices before processing starts, then runs each slice as its own StepExecution with its own reader, processor, writer, and metadata. This gives you: True independence between partitions — one partition’s failure doesn’t affect others A separate StepExecution row per partition in BATCH_STEP_EXECUTION — full visibility into per-partition progress The ability to distribute partitions across multiple JVMs (remote partitioning, covered in Article 22) Partitioning Architecture ManagerStep (PartitionStep) │ ├── Partitioner → creates N ExecutionContexts (one per partition) ├── PartitionHandler → distributes partitions to workers │ └── Worker Steps (run per partition) ├── ItemReader → reads only its slice of data ├── ItemProcessor └── ItemWriter The manager step runs once: it calls Partitioner.

Continue reading »

Performance Tuning: Chunk Size, Connection Pools, and Memory Management

Introduction A poorly tuned batch job can be 10–100x slower than a well-tuned one. The biggest gains come from a handful of settings — chunk size, MySQL JDBC rewrite, connection pool alignment, and avoiding unnecessary object creation. This article covers each systematically. Chunk Size — The Most Impactful Setting Chunk size determines how many items are processed per transaction. Too small = too many round trips to the database. Too large = long transactions, high memory pressure, slower rollback on failure.

Continue reading »

Primary Keys and Generated Values: IDENTITY, SEQUENCE, UUID

Introduction Primary key choice affects performance, scalability, and application design. This article covers every strategy JPA supports — from the simple AUTO_INCREMENT to UUID and composite keys — with the trade-offs of each. IDENTITY Strategy (MySQL AUTO_INCREMENT) GenerationType.IDENTITY delegates key generation to the database column’s auto-increment feature. This is the standard for MySQL. @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; Generated DDL (when ddl-auto=create): id BIGINT NOT NULL AUTO_INCREMENT How IDENTITY works with Hibernate IDENTITY has one important behaviour: Hibernate cannot batch INSERT statements when using IDENTITY.

Continue reading »

Projections and DTOs: Fetching Only What You Need

The Over-Fetching Problem By default, findAll() loads every column for every entity. A Product entity with 20 fields loads all 20 columns — even when a dropdown menu only needs id and name. This wastes bandwidth, memory, and query time. Projections let you define what shape the result should take, and Spring Data JPA generates a query that fetches only those columns. Interface Projections The simplest projection: declare an interface with getter methods matching entity field names.

Continue reading »

Repository Interfaces: CrudRepository, JpaRepository, and How They Work

Introduction Spring Data JPA’s repository abstraction eliminates the DAO boilerplate that every Java application used to require. You declare an interface, extend one of the repository base interfaces, and Spring generates a complete implementation at startup — find, save, delete, count, and more — with zero code written. The Repository Hierarchy Repository<T, ID> ← Marker interface — no methods │ └── CrudRepository<T, ID> ← Basic CRUD: save, find, delete, count │ └── PagingAndSortingRepository<T, ID> ← + findAll(Pageable), findAll(Sort) │ └── JpaRepository<T, ID> ← + flush, saveAndFlush, deleteInBatch Each interface adds more operations.

Continue reading »

Scheduling Batch Jobs: @Scheduled, Quartz, and Clustered Scheduling

Introduction A batch job that only runs manually is barely useful. Production jobs run on a schedule — nightly, hourly, after a file arrives. Spring Boot provides three scheduling options: Option Persistence Clustered Use when @Scheduled No No Simple cron on a single node Quartz Scheduler Yes (DB) Yes HA scheduling, persistent triggers External scheduler (Kubernetes CronJob, Airflow) Varies Yes Complex pipelines, dependency management @Scheduled — Simple Cron Trigger The simplest approach: annotate a method with @Scheduled and run the job from it.

Continue reading »