Portfolio
Loading Shiham's portfolio
Preparing the latest projects, skills, and contact paths with a quiet production-ready polish.
Initializing portfolio
Projects · Skills · Contact
Portfolio
Preparing the latest projects, skills, and contact paths with a quiet production-ready polish.
Initializing portfolio
Projects · Skills · Contact
A focused Java persistence sandbox for developers learning Spring Data JPA through course-domain entity mappings, repository queries, and PostgreSQL.
This personal learning project explores Spring Boot and Spring Data JPA through a compact online-course domain. It is intended for developers practicing persistence concepts rather than end users, and it focuses on how Java entities are mapped to a PostgreSQL schema.
The model connects authors, courses, sections, lectures, and resources using many-to-many, one-to-many, many-to-one, and one-to-one associations. It also demonstrates table-per-class inheritance for video, text, and file resources, plus embedded value objects and a composite order key.
The application is organized as a single Spring Boot module with JPA entities and an Author repository. Derived query methods and a transactional JPQL update are exercised from a CommandLineRunner, while Hibernate schema updates and SQL logging support local experimentation. I completed the project independently.
Related projects
Jan 2026 – Jun 2026
A multi-vendor commerce platform connecting buyers, sellers, and administrators through dedicated storefronts, dashboards, payments, chat, and personalized discovery.
A single Spring Boot application contains the domain entities and a Spring Data repository, with Hibernate persisting the model to a local PostgreSQL database. A CommandLineRunner invokes repository experiments at startup; no service, controller, or public API layer is implemented.
A hands-on learning project for practicing Spring Boot and Spring Data JPA fundamentals — entity mapping, relationship types, inheritance strategies, composite/embedded keys, and repository query methods.
This isn't a production app — it's a sandbox for experimenting with how JPA/Hibernate behaves, using a small "online course platform" domain model (authors, courses, sections, lectures, resources).
The core model represents a simple course platform:
erDiagram
AUTHOR }o--o{ COURSE : "authors_courses (many-to-many)"
COURSE ||--o{ SECTION : "one-to-many"
SECTION ||--o{ LECTURE : "one-to-many"
LECTURE ||--|| RESOURCE : "one-to-one"
Resource is a base class extended by three concrete resource types, using table-per-class inheritance:
Resource (id, name, size, url)
├── Video (+ length)
├── Text (+ content)
└── File (+ type)
There's also a standalone example under models/embedded/ demonstrating a composite primary key:
OrderId — an @Embeddable class combining username + orderDate, used as Order's @EmbeddedIdAddress — an @Embeddable value object embedded inside Order| Concept | Where it shows up |
|---|---|
@MappedSuperclass | BaseEntity — shared id, createdAt, lastModifiedAt, createdBy, lastModifiedBy fields |
@OneToMany / @ManyToOne | Course ↔ Section, Section ↔ Lecture |
@ManyToMany + @JoinTable | Author ↔ Course via authors_courses join table |
AuthorRepository demonstrates several ways Spring Data derives queries from method names, plus a custom JPQL update:
List<Author> findAllByFirstName(String fn);
List<Author> findAllByFirstNameIgnoreCase(String fn);
List<Author> findAllByFirstNameContainingIgnoreCase(String fn);
List<Author> findAllByFirstNameStartsWithIgnoreCase(String fn);
List<Author> findAllByFirstNameEndsWithIgnoreCase(String fn);
List<Author> findAllByFirstNameInIgnoreCase(List<String> firstNames);
@Modifying
@Transactional
@Query("UPDATE Author a SET a.age = :age WHERE a.id = :id")
void updateAuthor(int age, int id);
src/main/java/com/devlab/jpa/
├── JpaApplication.java # entry point + CommandLineRunner for experiments
├── models/
│ ├── BaseEntity.java # @MappedSuperclass with audit-style fields
│ ├── Author.java
│ ├── Course.java
│ ├── Section.java
│ ├── Lecture.java
│ ├── Resource.java # table-per-class inheritance root
│ ├── Video.java
│ ├── Text.java
│ ├── File.java
│ └── embedded/
│ ├── Address.java # @Embeddable
│ ├── Order.java # entity with composite key
│ └── OrderId.java # @EmbeddedId
├── repositories/
│ └── AuthorRepository.java
└── resources/
└── application.yml
Clone the repo
git clone https://github.com/theShihamAhamed/java-data-jpa_playground.git
cd java-data-jpa_playground
Create the database
CREATE DATABASE data_jpa;
Configure the connection
Database credentials live in src/main/resources/application.yml. Update them to match your local Postgres setup:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/data_jpa
username: postgres
password: your_password
This file currently has local defaults committed for convenience — if you make this a real project, move credentials to environment variables and add
application.ymlto.gitignoreinstead.
Run the application
./mvnw spring-boot:run
On Windows, use mvnw.cmd spring-boot:run instead.
show-sql: true is enabled, so generated SQL is printed to the console — useful for seeing exactly what Hibernate does for each mapping/query.JpaApplication's CommandLineRunner bean is where new repository calls get tried out during learning — swap out its contents to experiment with different queries or entity relationships.Personal learning project — feel free to use it as a reference.
The case-study preview is collapsed. Activate the button to make the full content available.
Aug 2025 – Oct 2025
A marketplace for verified Sri Lankan homestays, supporting guest bookings, host onboarding, admin approval, and test-mode payments.
Oct 2025 – Nov 2025
A full-stack developer Q&A platform where programmers can ask, answer, vote, save questions, explore tags, and generate AI-assisted responses.
@OneToOne |
Lecture ↔ Resource |
@Inheritance(strategy = TABLE_PER_CLASS) | Resource → Video, Text, File |
@Embeddable / @EmbeddedId | Address, OrderId → Order (composite key) |
| Derived query methods | AuthorRepository (see below) |
JPQL with @Query + @Modifying | Custom update query in AuthorRepository |
| Lombok on entities | @Data, @SuperBuilder, @NoArgsConstructor, @AllArgsConstructor, @EqualsAndHashCode(callSuper = true) |
The app starts on port 8081, and spring.jpa.hibernate.ddl-auto: update will auto-create/update the schema from the entities on startup.