diff --git a/docker-compose.yml b/docker-compose.yml index 4ab5416..acec0d3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,25 +1,26 @@ services: - # Oracle Database service - oracle-db: - image: container-registry.oracle.com/database/express:21.3.0-xe - container_name: photoalbum-oracle + # PostgreSQL Database service (migrated from Oracle) + postgres-db: + image: postgres:16-alpine + container_name: photoalbum-postgres environment: - - ORACLE_PWD=photoalbum - - ORACLE_CHARACTERSET=AL32UTF8 + - POSTGRES_DB=postgres + - POSTGRES_USER=photoalbum + - POSTGRES_PASSWORD=photoalbum + - POSTGRES_INITDB_ARGS=--encoding=UTF-8 ports: - - "1521:1521" - - "5500:5500" + - "5432:5432" volumes: - - oracle_data:/opt/oracle/oradata - - ./oracle-init:/opt/oracle/scripts/startup + - postgres_data:/var/lib/postgresql/data + - ./postgres-init:/docker-entrypoint-initdb.d networks: - photoalbum-network healthcheck: - test: ["CMD-SHELL", "echo 'SELECT 1 FROM DUAL;' | sqlplus -s photoalbum/photoalbum@//localhost:1521/XE || exit 1"] - interval: 30s - timeout: 10s - retries: 15 - start_period: 180s + test: ["CMD-SHELL", "pg_isready -U photoalbum"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s # Photo Album Java Application photoalbum-java-app: @@ -29,20 +30,19 @@ services: container_name: photoalbum-java-app environment: - SPRING_PROFILES_ACTIVE=docker - - SPRING_DATASOURCE_URL=jdbc:oracle:thin:@oracle-db:1521:XE - - SPRING_DATASOURCE_USERNAME=photoalbum - - SPRING_DATASOURCE_PASSWORD=photoalbum + - POSTGRES_USERNAME=photoalbum + - POSTGRES_PASSWORD=photoalbum ports: - "8080:8080" depends_on: - oracle-db: + postgres-db: condition: service_healthy networks: - photoalbum-network restart: on-failure volumes: - oracle_data: + postgres_data: networks: photoalbum-network: diff --git a/oracle-init/01-create-user.sql b/oracle-init/01-create-user.sql deleted file mode 100644 index 32ad600..0000000 --- a/oracle-init/01-create-user.sql +++ /dev/null @@ -1,36 +0,0 @@ --- This script runs automatically when Oracle XE container starts --- It creates the photoalbum user and grants necessary privileges - -ALTER SESSION SET "_ORACLE_SCRIPT"=true; - --- Create photoalbum user -CREATE USER photoalbum IDENTIFIED BY photoalbum; - --- Grant system privileges -GRANT CONNECT TO photoalbum; -GRANT RESOURCE TO photoalbum; -GRANT DBA TO photoalbum; -GRANT CREATE SESSION TO photoalbum; -GRANT CREATE TABLE TO photoalbum; -GRANT CREATE SEQUENCE TO photoalbum; -GRANT CREATE VIEW TO photoalbum; -GRANT CREATE PROCEDURE TO photoalbum; -GRANT CREATE TRIGGER TO photoalbum; -GRANT CREATE TYPE TO photoalbum; -GRANT CREATE SYNONYM TO photoalbum; -GRANT UNLIMITED TABLESPACE TO photoalbum; - --- Grant object privileges needed by Hibernate -GRANT SELECT ANY DICTIONARY TO photoalbum; -GRANT CREATE ANY INDEX TO photoalbum; -GRANT ALTER ANY INDEX TO photoalbum; -GRANT DROP ANY INDEX TO photoalbum; - --- Set default and temporary tablespace -ALTER USER photoalbum DEFAULT TABLESPACE USERS; -ALTER USER photoalbum TEMPORARY TABLESPACE TEMP; - --- Commit the changes -COMMIT; - -EXIT; \ No newline at end of file diff --git a/oracle-init/02-verify-user.sql b/oracle-init/02-verify-user.sql deleted file mode 100644 index 91c82a1..0000000 --- a/oracle-init/02-verify-user.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Verification script to check if photoalbum user exists -ALTER SESSION SET "_ORACLE_SCRIPT"=true; - --- Check if user exists -SELECT username, account_status, default_tablespace -FROM dba_users -WHERE username = 'PHOTOALBUM'; - --- Show granted privileges -SELECT grantee, privilege -FROM dba_sys_privs -WHERE grantee = 'PHOTOALBUM'; - -EXIT; \ No newline at end of file diff --git a/oracle-init/create-user.sh b/oracle-init/create-user.sh deleted file mode 100644 index c15ee5f..0000000 --- a/oracle-init/create-user.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# This script ensures the photoalbum user is created in Oracle XE - -# Wait for Oracle to be fully ready -echo "Waiting for Oracle to be ready..." -sleep 30 - -# Connect to Oracle as SYSTEM and create the photoalbum user -sqlplus -s system/photoalbum@//localhost:1521/XE <jar Photo Album - A simple photo storage and gallery application built with Spring Boot and Oracle DB + A simple photo storage and gallery application built with Spring Boot and PostgreSQL 1.8 @@ -46,10 +46,13 @@ spring-boot-starter-data-jpa - + + + - com.oracle.database.jdbc - ojdbc8 + org.postgresql + postgresql + 42.7.7 runtime diff --git a/postgres-init/01-init-db.sql b/postgres-init/01-init-db.sql new file mode 100644 index 0000000..b33bfc8 --- /dev/null +++ b/postgres-init/01-init-db.sql @@ -0,0 +1,29 @@ +-- Migrated from Oracle to PostgreSQL according to SQL check item 1: Use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). +-- PostgreSQL initialization script for photoalbum database +-- This script runs automatically when PostgreSQL container starts + +-- Note: The photoalbum user is created by the POSTGRES_USER environment variable +-- We only need to grant additional privileges if required + +-- Create database if not exists (though it's created by POSTGRES_DB env var) +-- The default database 'postgres' is already created + +-- Grant schema privileges to photoalbum user +GRANT ALL PRIVILEGES ON DATABASE postgres TO photoalbum; + +-- Grant privileges on public schema +GRANT ALL ON SCHEMA public TO photoalbum; + +-- Grant default privileges for future tables +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO photoalbum; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO photoalbum; + +-- Extension for UUID generation (if needed in future) +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +-- Log successful initialization +DO $$ +BEGIN + RAISE NOTICE 'PostgreSQL initialization completed successfully for photoalbum user'; +END $$; + diff --git a/src/main/java/com/photoalbum/controller/PhotoFileController.java b/src/main/java/com/photoalbum/controller/PhotoFileController.java index 2f31408..f66d9ae 100644 --- a/src/main/java/com/photoalbum/controller/PhotoFileController.java +++ b/src/main/java/com/photoalbum/controller/PhotoFileController.java @@ -17,7 +17,7 @@ import java.util.Optional; /** - * Controller for serving photo files from Oracle database BLOB storage + * Controller for serving photo files from PostgreSQL database BLOB storage */ @Controller @RequestMapping("/photo") @@ -32,7 +32,7 @@ public PhotoFileController(PhotoService photoService) { } /** - * Serves a photo file by ID from Oracle database BLOB storage + * Serves a photo file by ID from PostgreSQL database BLOB storage */ @GetMapping("/{id}") public ResponseEntity servePhoto(@PathVariable String id) { @@ -54,7 +54,7 @@ public ResponseEntity servePhoto(@PathVariable String id) { logger.info("Found photo: originalFileName={}, mimeType={}", photo.getOriginalFileName(), photo.getMimeType()); - // Get photo data from Oracle database BLOB + // Get photo data from PostgreSQL database BLOB byte[] photoData = photo.getPhotoData(); if (photoData == null || photoData.length == 0) { logger.error("No photo data found for photo ID {}", id); @@ -68,7 +68,7 @@ public ResponseEntity servePhoto(@PathVariable String id) { // Create resource from byte array Resource resource = new ByteArrayResource(photoData); - logger.info("Serving photo ID {} ({}, {} bytes) from Oracle database", + logger.info("Serving photo ID {} ({}, {} bytes) from PostgreSQL database", id, photo.getOriginalFileName(), photoData.length); // Return the photo data with appropriate content type and aggressive no-cache headers @@ -82,7 +82,7 @@ public ResponseEntity servePhoto(@PathVariable String id) { .header("X-Photo-Size", String.valueOf(photoData.length)) .body(resource); } catch (Exception ex) { - logger.error("Error serving photo with ID {} from Oracle database", id, ex); + logger.error("Error serving photo with ID {} from PostgreSQL database", id, ex); return ResponseEntity.status(500).build(); } } diff --git a/src/main/java/com/photoalbum/model/Photo.java b/src/main/java/com/photoalbum/model/Photo.java index d1cea3e..9273e5e 100644 --- a/src/main/java/com/photoalbum/model/Photo.java +++ b/src/main/java/com/photoalbum/model/Photo.java @@ -34,7 +34,7 @@ public class Photo { private String originalFileName; /** - * Binary photo data stored directly in Oracle database + * Binary photo data stored directly in PostgreSQL database */ @Lob @Column(name = "photo_data", nullable = true) @@ -57,10 +57,11 @@ public class Photo { /** * File size in bytes + * Migrated from Oracle to PostgreSQL according to java check item 1: Convert all table and column names from uppercase to lowercase in JPA annotations. */ @NotNull @Positive - @Column(name = "file_size", nullable = false, columnDefinition = "NUMBER(19,0)") + @Column(name = "file_size", nullable = false) private Long fileSize; /** @@ -73,9 +74,10 @@ public class Photo { /** * Timestamp of upload + * Migrated from Oracle to PostgreSQL according to java check item 1: Convert all table and column names from uppercase to lowercase in JPA annotations. */ @NotNull - @Column(name = "uploaded_at", nullable = false, columnDefinition = "TIMESTAMP DEFAULT SYSTIMESTAMP") + @Column(name = "uploaded_at", nullable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") private LocalDateTime uploadedAt; /** diff --git a/src/main/java/com/photoalbum/repository/PhotoRepository.java b/src/main/java/com/photoalbum/repository/PhotoRepository.java index 135799a..a8f3ee0 100644 --- a/src/main/java/com/photoalbum/repository/PhotoRepository.java +++ b/src/main/java/com/photoalbum/repository/PhotoRepository.java @@ -17,85 +17,92 @@ public interface PhotoRepository extends JpaRepository { /** * Find all photos ordered by upload date (newest first) + * Migrated from Oracle to PostgreSQL according to java check item 6: In SQL string literals, use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). * @return List of photos ordered by upload date descending */ - @Query(value = "SELECT ID, ORIGINAL_FILE_NAME, PHOTO_DATA, STORED_FILE_NAME, FILE_PATH, FILE_SIZE, " + - "MIME_TYPE, UPLOADED_AT, WIDTH, HEIGHT " + - "FROM PHOTOS " + - "ORDER BY UPLOADED_AT DESC", + @Query(value = "SELECT id, original_file_name, photo_data, stored_file_name, file_path, file_size, " + + "mime_type, uploaded_at, width, height " + + "FROM photos " + + "ORDER BY uploaded_at DESC", nativeQuery = true) List findAllOrderByUploadedAtDesc(); /** * Find photos uploaded before a specific photo (for navigation) + * Migrated from Oracle to PostgreSQL according to java check item 17: Replace ROWNUM pagination with LIMIT/OFFSET in native SQL queries. + * Migrated from Oracle to PostgreSQL according to java check item 6: In SQL string literals, use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). * @param uploadedAt The upload timestamp to compare against * @return List of photos uploaded before the given timestamp */ - @Query(value = "SELECT * FROM (" + - "SELECT ID, ORIGINAL_FILE_NAME, PHOTO_DATA, STORED_FILE_NAME, FILE_PATH, FILE_SIZE, " + - "MIME_TYPE, UPLOADED_AT, WIDTH, HEIGHT, ROWNUM as RN " + - "FROM PHOTOS " + - "WHERE UPLOADED_AT < :uploadedAt " + - "ORDER BY UPLOADED_AT DESC" + - ") WHERE ROWNUM <= 10", + @Query(value = "SELECT id, original_file_name, photo_data, stored_file_name, file_path, file_size, " + + "mime_type, uploaded_at, width, height " + + "FROM photos " + + "WHERE uploaded_at < :uploadedAt " + + "ORDER BY uploaded_at DESC " + + "LIMIT 10", nativeQuery = true) List findPhotosUploadedBefore(@Param("uploadedAt") LocalDateTime uploadedAt); /** * Find photos uploaded after a specific photo (for navigation) + * Migrated from Oracle to PostgreSQL according to java check item 6: In SQL string literals, use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). * @param uploadedAt The upload timestamp to compare against * @return List of photos uploaded after the given timestamp */ - @Query(value = "SELECT ID, ORIGINAL_FILE_NAME, PHOTO_DATA, STORED_FILE_NAME, " + - "NVL(FILE_PATH, 'default_path') as FILE_PATH, FILE_SIZE, " + - "MIME_TYPE, UPLOADED_AT, WIDTH, HEIGHT " + - "FROM PHOTOS " + - "WHERE UPLOADED_AT > :uploadedAt " + - "ORDER BY UPLOADED_AT ASC", + @Query(value = "SELECT id, original_file_name, photo_data, stored_file_name, " + + "COALESCE(file_path, 'default_path') as file_path, file_size, " + + "mime_type, uploaded_at, width, height " + + "FROM photos " + + "WHERE uploaded_at > :uploadedAt " + + "ORDER BY uploaded_at ASC", nativeQuery = true) List findPhotosUploadedAfter(@Param("uploadedAt") LocalDateTime uploadedAt); /** - * Find photos by upload month using Oracle TO_CHAR function - Oracle specific + * Find photos by upload month - migrated to PostgreSQL + * Migrated from Oracle to PostgreSQL according to java check item 4: Replace TO_CHAR date functions with EXTRACT in SQL statements. + * Migrated from Oracle to PostgreSQL according to java check item 6: In SQL string literals, use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). * @param year The year to search for * @param month The month to search for * @return List of photos uploaded in the specified month */ - @Query(value = "SELECT ID, ORIGINAL_FILE_NAME, PHOTO_DATA, STORED_FILE_NAME, FILE_PATH, FILE_SIZE, " + - "MIME_TYPE, UPLOADED_AT, WIDTH, HEIGHT " + - "FROM PHOTOS " + - "WHERE TO_CHAR(UPLOADED_AT, 'YYYY') = :year " + - "AND TO_CHAR(UPLOADED_AT, 'MM') = :month " + - "ORDER BY UPLOADED_AT DESC", + @Query(value = "SELECT id, original_file_name, photo_data, stored_file_name, file_path, file_size, " + + "mime_type, uploaded_at, width, height " + + "FROM photos " + + "WHERE EXTRACT(YEAR FROM uploaded_at)::text = :year " + + "AND LPAD(EXTRACT(MONTH FROM uploaded_at)::text, 2, '0') = :month " + + "ORDER BY uploaded_at DESC", nativeQuery = true) List findPhotosByUploadMonth(@Param("year") String year, @Param("month") String month); /** - * Get paginated photos using Oracle ROWNUM - Oracle specific pagination + * Get paginated photos - migrated to PostgreSQL + * Migrated from Oracle to PostgreSQL according to java check item 17: Replace ROWNUM pagination with LIMIT/OFFSET in native SQL queries. + * Migrated from Oracle to PostgreSQL according to java check item 6: In SQL string literals, use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). * @param startRow Starting row number (1-based) * @param endRow Ending row number * @return List of photos within the specified row range */ - @Query(value = "SELECT * FROM (" + - "SELECT P.*, ROWNUM as RN FROM (" + - "SELECT ID, ORIGINAL_FILE_NAME, PHOTO_DATA, STORED_FILE_NAME, FILE_PATH, FILE_SIZE, " + - "MIME_TYPE, UPLOADED_AT, WIDTH, HEIGHT " + - "FROM PHOTOS ORDER BY UPLOADED_AT DESC" + - ") P WHERE ROWNUM <= :endRow" + - ") WHERE RN >= :startRow", + @Query(value = "SELECT id, original_file_name, photo_data, stored_file_name, file_path, file_size, " + + "mime_type, uploaded_at, width, height " + + "FROM photos " + + "ORDER BY uploaded_at DESC " + + "LIMIT :endRow - :startRow + 1 OFFSET :startRow - 1", nativeQuery = true) List findPhotosWithPagination(@Param("startRow") int startRow, @Param("endRow") int endRow); /** - * Find photos with file size statistics using Oracle analytical functions - Oracle specific + * Find photos with file size statistics - migrated to PostgreSQL + * Migrated from Oracle to PostgreSQL according to java check item 3: Replace Oracle-specific SQL functions with PostgreSQL equivalents. Like RANK() to ROW_NUMBER() + * Migrated from Oracle to PostgreSQL according to java check item 6: In SQL string literals, use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE). * @return List of photos with running totals and rankings */ - @Query(value = "SELECT ID, ORIGINAL_FILE_NAME, PHOTO_DATA, STORED_FILE_NAME, FILE_PATH, FILE_SIZE, " + - "MIME_TYPE, UPLOADED_AT, WIDTH, HEIGHT, " + - "RANK() OVER (ORDER BY FILE_SIZE DESC) as SIZE_RANK, " + - "SUM(FILE_SIZE) OVER (ORDER BY UPLOADED_AT ROWS UNBOUNDED PRECEDING) as RUNNING_TOTAL " + - "FROM PHOTOS " + - "ORDER BY UPLOADED_AT DESC", + @Query(value = "SELECT id, original_file_name, photo_data, stored_file_name, file_path, file_size, " + + "mime_type, uploaded_at, width, height, " + + "ROW_NUMBER() OVER (ORDER BY file_size DESC) as size_rank, " + + "SUM(file_size) OVER (ORDER BY uploaded_at ROWS UNBOUNDED PRECEDING) as running_total " + + "FROM photos " + + "ORDER BY uploaded_at DESC", nativeQuery = true) List findPhotosWithStatistics(); -} \ No newline at end of file +} diff --git a/src/main/java/com/photoalbum/service/impl/PhotoServiceImpl.java b/src/main/java/com/photoalbum/service/impl/PhotoServiceImpl.java index fa379a5..e4064f1 100644 --- a/src/main/java/com/photoalbum/service/impl/PhotoServiceImpl.java +++ b/src/main/java/com/photoalbum/service/impl/PhotoServiceImpl.java @@ -139,7 +139,7 @@ public UploadResult uploadPhoto(MultipartFile file) { // Create photo entity with database BLOB storage Photo photo = new Photo( file.getOriginalFilename(), - photoData, // Store actual photo data in Oracle database + photoData, // Store actual photo data in PostgreSQL database storedFileName, relativePath, // Keep for compatibility, not used for serving file.getSize(), @@ -155,10 +155,10 @@ public UploadResult uploadPhoto(MultipartFile file) { result.setSuccess(true); result.setPhotoId(photo.getId()); - logger.info("Successfully uploaded photo {} with ID {} to Oracle database", + logger.info("Successfully uploaded photo {} with ID {} to PostgreSQL database", file.getOriginalFilename(), photo.getId()); } catch (Exception ex) { - logger.error("Error saving photo to Oracle database for {}", file.getOriginalFilename(), ex); + logger.error("Error saving photo to PostgreSQL database for {}", file.getOriginalFilename(), ex); result.setSuccess(false); result.setErrorMessage("Error saving photo to database. Please try again."); } @@ -185,13 +185,13 @@ public boolean deletePhoto(String id) { Photo photo = photoOpt.get(); - // Delete from Oracle database (photos stored as BLOB) + // Delete from PostgreSQL database (photos stored as BLOB) photoRepository.delete(photo); - logger.info("Successfully deleted photo ID {} from Oracle database", id); + logger.info("Successfully deleted photo ID {} from PostgreSQL database", id); return true; } catch (Exception ex) { - logger.error("Error deleting photo with ID {} from Oracle database", id, ex); + logger.error("Error deleting photo with ID {} from PostgreSQL database", id, ex); throw new RuntimeException("Error deleting photo", ex); } } diff --git a/src/main/resources/application-docker.properties b/src/main/resources/application-docker.properties index 8dff306..44b20fc 100644 --- a/src/main/resources/application-docker.properties +++ b/src/main/resources/application-docker.properties @@ -1,8 +1,11 @@ -# Docker-specific configuration for Oracle DB -spring.datasource.url=jdbc:oracle:thin:@oracle-db:1521:XE -spring.datasource.username=photoalbum -spring.datasource.password=photoalbum -spring.datasource.driver-class-name=oracle.jdbc.OracleDriver +# Migrated from Oracle to PostgreSQL according to property check item 1: Change JDBC URL from Oracle to PostgreSQL. +# Migrated from Oracle to PostgreSQL according to property check item 2: Replace Oracle JDBC driver class with PostgreSQL driver class. +# Migrated from Oracle to PostgreSQL according to property check item 3: Change Hibernate dialect from Oracle to PostgreSQL. +# Docker-specific configuration for PostgreSQL DB +spring.datasource.url=jdbc:postgresql://postgres-db:5432/postgres +spring.datasource.username=${POSTGRES_USERNAME:photoalbum} +spring.datasource.password=${POSTGRES_PASSWORD:photoalbum} +spring.datasource.driver-class-name=org.postgresql.Driver # Character encoding server.servlet.encoding.charset=UTF-8 @@ -10,7 +13,7 @@ server.servlet.encoding.enabled=true server.servlet.encoding.force=true # JPA Configuration for Docker -spring.jpa.database-platform=org.hibernate.dialect.OracleDialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cc00cc2..032d382 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -6,14 +6,19 @@ server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true -# Oracle Database Configuration -spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE -spring.datasource.username=photoalbum -spring.datasource.password=photoalbum -spring.datasource.driver-class-name=oracle.jdbc.OracleDriver +# Migrated from Oracle to PostgreSQL according to property check item 1: Change JDBC URL from Oracle to PostgreSQL. +# Migrated from Oracle to PostgreSQL according to property check item 2: Replace Oracle JDBC driver class with PostgreSQL driver class. +# Migrated from Oracle to PostgreSQL according to property check item 3: Change Hibernate dialect from Oracle to PostgreSQL. +# Migrated from Oracle to PostgreSQL according to property check item 4: If port property is Oracle specific, then replace with PostgreSQL equivalents. +# Migrated from Oracle to PostgreSQL according to property check item 5: Change username and password to environment variable placeholder. +# PostgreSQL Database Configuration +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=${POSTGRES_USERNAME:photoalbum} +spring.datasource.password=${POSTGRES_PASSWORD:photoalbum} +spring.datasource.driver-class-name=org.postgresql.Driver # JPA Configuration -spring.jpa.database-platform=org.hibernate.dialect.OracleDialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true