A photo gallery application built with Spring Boot and Oracle Database, featuring drag-and-drop upload, responsive gallery view, and full-size photo details with navigation.
- 📤 Photo Upload: Drag-and-drop or click to upload multiple photos
- 🖼️ Gallery View: Responsive grid layout for browsing uploaded photos
- 🔍 Photo Detail View: Click any photo to view full-size with metadata and navigation
- 📊 Metadata Display: View file size, dimensions, aspect ratio, and upload timestamp
- ⬅️➡️ Photo Navigation: Previous/Next buttons to browse through photos
- ✅ Validation: File type and size validation (JPEG, PNG, GIF, WebP; max 10MB)
- 🗄️ Database Storage: Photo data stored as BLOBs in Oracle Database
- 🗑️ Delete Photos: Remove photos from both gallery and detail views
- 🎨 Modern UI: Clean, responsive design with Bootstrap 5
- Framework: Spring Boot 2.7.18 (Java 8)
- Database: Oracle Database 21c Express Edition
- Templating: Thymeleaf
- Build Tool: Maven
- Frontend: Bootstrap 5.3.0, Vanilla JavaScript
- Containerization: Docker & Docker Compose
- Docker Desktop installed and running
- Docker Compose (included with Docker Desktop)
- Minimum 4GB RAM available for Oracle DB container
-
Clone the repository:
git clone https://github.com/Azure-Samples/PhotoAlbum-Java.git cd PhotoAlbum-Java -
Configure credentials and start the application:
# Copy the template and set strong, unique passwords in .env (git-ignored) cp .env.example .env # Use docker-compose directly (credentials are read from .env) docker-compose up --build -d
This will:
- Start Oracle Database 21c Express Edition container
- Build the Java Spring Boot application
- Start the Photo Album application container
- Automatically create the database schema using JPA/Hibernate
-
Wait for services to start:
- Oracle DB takes 2-3 minutes to initialize on first run
- Application will start once Oracle is healthy
-
Access the application:
- Open your browser and navigate to: http://localhost:8080
- The application should be running and ready to use
- Image:
container-registry.oracle.com/database/express:21.3.0-xe - Ports:
1521(database) - mapped to host port 15215500(Enterprise Manager) - mapped to host port 5500
- Database:
XE(Express Edition) - Schema:
photoalbum - Username/Password: provided via the
APP_USER/APP_USER_PASSWORDvariables in.env(never hard-coded)
- Port:
8080(mapped to host port 8080) - Framework: Spring Boot 2.7.18
- Java Version: 8
- Database: Connects to Oracle container
- Photo Storage: All photos stored as BLOBs in database (no file system storage)
- UUID System: Each photo gets a globally unique identifier for cache-busting
The application uses Spring Data JPA with Hibernate for automatic schema management:
- Automatic Schema Creation: Hibernate automatically creates tables and indexes
- User Creation: Oracle init scripts create the
photoalbumuser - No Manual Setup Required: Everything is handled automatically
The application creates the following table structure in Oracle:
ID(VARCHAR2(36), Primary Key, UUID Generated)ORIGINAL_FILE_NAME(VARCHAR2(255), Not Null)STORED_FILE_NAME(VARCHAR2(255), Not Null)FILE_PATH(VARCHAR2(500), Nullable)FILE_SIZE(NUMBER, Not Null)MIME_TYPE(VARCHAR2(50), Not Null)UPLOADED_AT(TIMESTAMP, Not Null, Default SYSTIMESTAMP)WIDTH(NUMBER, Nullable)HEIGHT(NUMBER, Nullable)PHOTO_DATA(BLOB, Not Null)
IDX_PHOTOS_UPLOADED_AT(Index on UPLOADED_AT for chronological queries)
- Java:
UUID.randomUUID().toString()generates unique identifiers - Benefits: Eliminates browser caching issues, globally unique across databases
- Format: Standard UUID format (36 characters with hyphens)
- Photos: Stored as BLOB data directly in the database
- Benefits:
- No file system dependencies
- ACID compliance for photo operations
- Simplified backup and migration
- Perfect for containerized deployments
- Trade-offs: Database size increases, but suitable for moderate photo volumes
- Install Oracle Database (or use Oracle XE)
- Create database user (choose your own strong password; grant least
privilege only — do NOT grant DBA):
CREATE USER photoalbum IDENTIFIED BY "<your-strong-password>"; GRANT CREATE SESSION, CREATE TABLE, CREATE SEQUENCE, CREATE VIEW, CREATE PROCEDURE, CREATE TRIGGER, CREATE TYPE, CREATE SYNONYM TO photoalbum; ALTER USER photoalbum QUOTA UNLIMITED ON USERS;
- Provide credentials via environment variables (do not hard-code them
in
application.properties):export SPRING_DATASOURCE_URL="jdbc:oracle:thin:@localhost:1521:XE" export SPRING_DATASOURCE_USERNAME="photoalbum" export SPRING_DATASOURCE_PASSWORD="<your-strong-password>"
- Run the application:
mvn spring-boot:run
# Build the JAR file
mvn clean package
# Run the JAR file
java -jar target/photo-album-1.0.0.jar-
Oracle container won't start:
# Check container logs docker-compose logs oracle-db # Increase Docker memory allocation to at least 4GB
-
Database connection errors:
# Verify Oracle is ready (credentials come from your .env values) docker exec -it photoalbum-oracle sh -c 'sqlplus "$APP_USER/$APP_USER_PASSWORD@//localhost:1521/FREEPDB1"'
-
Permission errors:
# Check Oracle init scripts ran docker-compose logs oracle-db | grep "setup"
-
View application logs:
docker-compose logs photoalbum-java-app
-
Rebuild application:
docker-compose up --build
-
Reset database (nuclear option):
docker-compose down -v docker-compose up --build
# Stop services
docker-compose down
# Stop and remove all data (including database)
docker-compose down -vOracle Enterprise Manager is available at http://localhost:5500/em for database administration:
- Username:
system - Password: the
ORACLE_PASSWORDvalue you set in.env - Container:
XE
- Oracle XE has limitations (max 2 CPU threads, 2GB RAM, 12GB storage)
- BLOB storage in database impacts performance at scale
- Suitable for development and small-scale deployments
PhotoAlbum/
├── src/ # Java source code
├── oracle-init/ # Oracle initialization scripts
├── docker-compose.yml # Oracle + Application services
├── Dockerfile # Application container build
├── pom.xml # Maven dependencies and build config
└── README.md # Project documentation
When contributing to this project:
- Follow Spring Boot best practices
- Maintain database compatibility
- Ensure UI/UX consistency
- Test both local Docker and Azure deployment scenarios
- Update documentation for any architectural changes
- Preserve UUID system integrity
- Add appropriate tests for new features
This project is provided as-is for educational and demonstration purposes.