From b769d797d2d3271db8429c540105db99f4334996 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari <115209826+JuniorPrice@users.noreply.github.com>
Date: Thu, 21 May 2026 08:34:00 +0400
Subject: [PATCH 01/14] prepare base file structure
---
.../oraclequantapi/controllers/OracleQuantController.java | 4 ++++
.../oraclequantapi/models/OracleQuantRecord.java | 4 ++++
.../oraclequantapi/repositories/OracleQuantRepository.java | 4 ++++
.../oraclequantapi/services/OracleQuantService.java | 4 ++++
4 files changed, 16 insertions(+)
create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java
create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
new file mode 100644
index 0000000..c17aa22
--- /dev/null
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
@@ -0,0 +1,4 @@
+package com.oraclequantapi.oraclequantapi.controllers;
+
+public class OracleQuantController {
+}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
new file mode 100644
index 0000000..be01689
--- /dev/null
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
@@ -0,0 +1,4 @@
+package com.oraclequantapi.oraclequantapi.models;
+
+public class OracleQuantRecord {
+}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java
new file mode 100644
index 0000000..b93a778
--- /dev/null
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java
@@ -0,0 +1,4 @@
+package com.oraclequantapi.oraclequantapi.repositories;
+
+public interface OracleQuantRepository {
+}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
new file mode 100644
index 0000000..1ae5fe3
--- /dev/null
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
@@ -0,0 +1,4 @@
+package com.oraclequantapi.oraclequantapi.services;
+
+public class OracleQuantService {
+}
From 76e21bf57450530e21138c204ddbd542ea00e443 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari <115209826+JuniorPrice@users.noreply.github.com>
Date: Thu, 21 May 2026 08:35:29 +0400
Subject: [PATCH 02/14] set requaired dependencies
---
pom.xml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/pom.xml b/pom.xml
index 20909d2..793b7bd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,6 +40,18 @@
spring-boot-starter-test
test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+ com.oracle.database.jdbc
+ ojdbc11
+ runtime
+
From ef1ac56eac1410d44f2791c7bf07c85098264d02 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari <115209826+JuniorPrice@users.noreply.github.com>
Date: Thu, 21 May 2026 09:56:34 +0400
Subject: [PATCH 03/14] prepare basic controller functions
---
.../controllers/OracleQuantController.java | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
index c17aa22..8cfa102 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
@@ -1,4 +1,35 @@
package com.oraclequantapi.oraclequantapi.controllers;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(path = "/OracleQuant")
public class OracleQuantController {
+
+ @GetMapping(path = "/Convert")
+ public List Convert(@PathVariable String value) {
+ return null;
+ }
+
+ @GetMapping(path = "/Fetch")
+ public List fetch(@PathVariable String value) {
+ return null;
+ }
+
+ @GetMapping(path = "/FetchAll")
+ public List fetchAll() {
+ return null;
+ }
+
+ @PutMapping(path = "/Update")
+ public List Update(@PathVariable String value) {
+ return null;
+ }
+
+ @DeleteMapping(path = "/Delete")
+ public List delete(@PathVariable String value) {
+ return null;
+ }
}
From dfdad7ab65b63eb89baabd857b17a04faa7ea7c4 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari <115209826+JuniorPrice@users.noreply.github.com>
Date: Thu, 21 May 2026 12:05:09 +0400
Subject: [PATCH 04/14] prepare The Converter
---
.../controllers/OracleQuantController.java | 8 +-
.../oraclequantapi/services/Converter.java | 85 +++++++++++++++++++
2 files changed, 89 insertions(+), 4 deletions(-)
create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
index 8cfa102..7d6494b 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
@@ -9,12 +9,12 @@
public class OracleQuantController {
@GetMapping(path = "/Convert")
- public List Convert(@PathVariable String value) {
+ public List Convert(@PathVariable String input) {
return null;
}
@GetMapping(path = "/Fetch")
- public List fetch(@PathVariable String value) {
+ public List fetch(@PathVariable String input) {
return null;
}
@@ -24,12 +24,12 @@ public List fetchAll() {
}
@PutMapping(path = "/Update")
- public List Update(@PathVariable String value) {
+ public List Update(@PathVariable String input) {
return null;
}
@DeleteMapping(path = "/Delete")
- public List delete(@PathVariable String value) {
+ public List delete(@PathVariable String input) {
return null;
}
}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
new file mode 100644
index 0000000..319907b
--- /dev/null
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
@@ -0,0 +1,85 @@
+package com.oraclequantapi.oraclequantapi.services;
+
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@Service
+public class Converter {
+
+ private List list;
+ private String input;
+
+ public Converter() {
+ }
+
+ public List Convert(String input) {
+ this.input = input.trim().toLowerCase();
+ String[] inputArray = input.split("");
+ boolean checked = checkInput(inputArray);
+ if (!checked) {
+ return null;
+ }
+
+ list = new ArrayList<>();
+ list = valueToInt(inputArray);
+ list = backageSize(list);
+ return list;
+ }
+
+ public boolean checkInput(String[] input) {
+ for (String s : input) {
+ if (s.isEmpty() || s.matches("^[a-z_]*$")) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public List backageSize(List valuesList) {
+ List backageSizeList = new ArrayList<>();
+ int backageCount = 0;
+ int count = 0;
+ int size = 0;
+
+ for (Integer integer : valuesList) {
+ if (backageCount == 0) {
+ backageCount = integer;
+ } else if (count < backageCount) {
+ size += integer;
+ count++;
+ } else {
+ backageSizeList.add(size);
+ count = 0;
+ size = 0;
+ backageCount = 0;
+ }
+ }
+ return backageSizeList;
+ }
+
+ public List valueToInt(String[] inputs) {
+ List valueList = new ArrayList<>();
+ int value = 0;
+
+ String[] valid = "_abcdefghijklmnopqrstuvwxyz".split("");
+
+ for (int i = 0; i < inputs.length; i++) {
+ for (int j = 0; j < valid.length; j++) {
+ if (inputs[i].equals(valid[j])) {
+ value += j;
+ break;
+ }
+ }
+
+ if (!inputs[i].equals("z")) {
+ valueList.add(value);
+ value = 0;
+ }
+ }
+
+ return valueList;
+ }
+}
From 2dacd8977fb83429196c115530cd1770c858b87e Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari <115209826+JuniorPrice@users.noreply.github.com>
Date: Thu, 21 May 2026 12:11:44 +0400
Subject: [PATCH 05/14] some changes in converter
---
.../oraclequantapi/services/Converter.java | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
index 319907b..825c037 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
@@ -9,22 +9,18 @@
@Service
public class Converter {
- private List list;
- private String input;
-
public Converter() {
}
public List Convert(String input) {
- this.input = input.trim().toLowerCase();
- String[] inputArray = input.split("");
+ String input1 = input.trim().toLowerCase();
+ String[] inputArray = input1.split("");
boolean checked = checkInput(inputArray);
if (!checked) {
return null;
}
- list = new ArrayList<>();
- list = valueToInt(inputArray);
+ List list = valueToInt(inputArray);
list = backageSize(list);
return list;
}
@@ -66,15 +62,15 @@ public List valueToInt(String[] inputs) {
String[] valid = "_abcdefghijklmnopqrstuvwxyz".split("");
- for (int i = 0; i < inputs.length; i++) {
+ for (String input : inputs) {
for (int j = 0; j < valid.length; j++) {
- if (inputs[i].equals(valid[j])) {
+ if (input.equals(valid[j])) {
value += j;
break;
}
}
- if (!inputs[i].equals("z")) {
+ if (!input.equals("z")) {
valueList.add(value);
value = 0;
}
From 03581b17354a6956e701e84c7db9c4171ae863ac Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 16:36:23 +0400
Subject: [PATCH 06/14] correct converter.java logic & prepare Repository
interface & prepare change log file
---
CHANGELOG.md | 8 +++++++
.../repositories/OracleQuantRepository.java | 7 +++++-
.../oraclequantapi/services/Converter.java | 24 +++++++++++--------
3 files changed, 28 insertions(+), 11 deletions(-)
create mode 100644 CHANGELOG.md
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..e1678da
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,8 @@
+# Changelog
+
+## v0.0.1 - Initial Release
+- Package Measurement Conversion endpoint (GET /convert-measurements)
+- History endpoints: GET all, GET by id, PUT/PATCH update, DELETE clear
+- Oracle XE database persistence for request history
+- Input validation and conversion algorithm
+- Logging with rolling file appender (7-day retention)
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java
index b93a778..20e582d 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/OracleQuantRepository.java
@@ -1,4 +1,9 @@
package com.oraclequantapi.oraclequantapi.repositories;
-public interface OracleQuantRepository {
+import com.oraclequantapi.oraclequantapi.models.OracleQuantRecord;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface OracleQuantRepository extends JpaRepository {
}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
index 825c037..e38f4d5 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
@@ -27,7 +27,7 @@ public List Convert(String input) {
public boolean checkInput(String[] input) {
for (String s : input) {
- if (s.isEmpty() || s.matches("^[a-z_]*$")) {
+ if (s.isEmpty() || !s.matches("^[a-z_]*$")) {
return false;
}
}
@@ -43,15 +43,19 @@ public List backageSize(List valuesList) {
for (Integer integer : valuesList) {
if (backageCount == 0) {
backageCount = integer;
- } else if (count < backageCount) {
+ } else {
size += integer;
count++;
- } else {
- backageSizeList.add(size);
- count = 0;
- size = 0;
- backageCount = 0;
}
+ if (backageCount == count) {
+ backageSizeList.add(size);
+ count = 0;
+ size = 0;
+ backageCount = 0;
+ }
+ }
+ if (count > 0) {
+ backageSizeList.add(size);
}
return backageSizeList;
}
@@ -62,15 +66,15 @@ public List valueToInt(String[] inputs) {
String[] valid = "_abcdefghijklmnopqrstuvwxyz".split("");
- for (String input : inputs) {
+ for (int i =0; i < inputs.length; i++) {
for (int j = 0; j < valid.length; j++) {
- if (input.equals(valid[j])) {
+ if (inputs[i].equals(valid[j])) {
value += j;
break;
}
}
- if (!input.equals("z")) {
+ if (!inputs[i].equals("z") || i == inputs.length -1) {
valueList.add(value);
value = 0;
}
From 68732b992beaf28e7843fd6b55a3c9a1e8734ed8 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 22:02:37 +0400
Subject: [PATCH 07/14] prepare application.prorerties file for database
connection
---
src/main/resources/application.properties | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 99d0060..71c42d5 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,13 @@
spring.application.name=oraclequantapi
+
+# Oracle XE datasource
+spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1
+spring.datasource.username=system
+spring.datasource.password=29999login
+spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
+
+# JPA / Hibernate settings
+# "update" creates/updates tables automatically ? safe for development
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.database-platform=org.hibernate.dialect.OracleDialect
+spring.jpa.show-sql=true
From 9f322c0198d15c976f9365ec1fb573508e0fc238 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 22:36:44 +0400
Subject: [PATCH 08/14] prepare OrackeQuantService.java file
---
.../services/OracleQuantService.java | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
index 1ae5fe3..143b246 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
@@ -1,4 +1,59 @@
package com.oraclequantapi.oraclequantapi.services;
+import com.oraclequantapi.oraclequantapi.models.OracleQuantRecord;
+import com.oraclequantapi.oraclequantapi.repositories.OracleQuantRepository;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Service
public class OracleQuantService {
+
+ private final Converter converter;
+ private final OracleQuantRepository repository;
+
+ public OracleQuantService(Converter converter, OracleQuantRepository repository) {
+ this.converter = converter;
+ this.repository = repository;
+ }
+
+ public List convertMeasurements(String input, String sourceIp) {
+ List result = converter.Convert(input);
+
+ OracleQuantRecord record = new OracleQuantRecord();
+ record.setTimestamp(LocalDateTime.now());
+ record.setSourceIpAddress(sourceIp);
+ record.setInput(input);
+ record.setOutput(result != null ? result.toString() : null);
+ repository.save(record);
+
+ return result;
+ }
+
+ public List getAllHistory() {
+ return repository.findAll();
+ }
+
+ public Optional getHistoryById(Integer id) {
+ return repository.findById(id);
+ }
+
+ public OracleQuantRecord updateHistory(Integer id, OracleQuantRecord updated) {
+ OracleQuantRecord record = repository.findById(id)
+ .orElseThrow(() -> new RuntimeException("Record not found: " + id));
+ record.setInput(updated.getInput());
+ record.setOutput(updated.getOutput());
+ record.setSourceIpAddress(updated.getSourceIpAddress());
+ return repository.save(record);
+ }
+
+ public void clearHistory() {
+ repository.deleteAll();
+ }
+
+ public void deleteHistoryById(Integer id) {
+ repository.deleteById(id);
+ }
}
From 76f1fd638c7f1ba9790c87a060b7788d1c4444e4 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 22:42:53 +0400
Subject: [PATCH 09/14] implement history record entity file and new release
recorded in changelog file
---
CHANGELOG.md | 5 ++
.../models/OracleQuantRecord.java | 62 +++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1678da..f3514ce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## v0.0.2 - Converter fixes and service layer
+- Fixed conversion algorithm: corrected `checkInput` inversion, `backageCount` reset, and post-loop flush
+- Added `OracleQuantService` with history CRUD operations
+- Added `OracleQuantRecord` JPA entity with id, timestamp, source_ip, input, output fields
+
## v0.0.1 - Initial Release
- Package Measurement Conversion endpoint (GET /convert-measurements)
- History endpoints: GET all, GET by id, PUT/PATCH update, DELETE clear
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
index be01689..17637f9 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
@@ -1,4 +1,66 @@
package com.oraclequantapi.oraclequantapi.models;
+import jakarta.persistence.*;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "conversion_history")
public class OracleQuantRecord {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ private LocalDateTime timestamp;
+
+ @Column(name = "source_ip_address")
+ private String sourceIpAddress;
+
+ @Column(columnDefinition = "TEXT")
+ private String input;
+
+ @Column(columnDefinition = "TEXT")
+ private String output;
+
+ public OracleQuantRecord() {}
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public LocalDateTime getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(LocalDateTime timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getSourceIpAddress() {
+ return sourceIpAddress;
+ }
+
+ public void setSourceIpAddress(String sourceIpAddress) {
+ this.sourceIpAddress = sourceIpAddress;
+ }
+
+ public String getInput() {
+ return input;
+ }
+
+ public void setInput(String input) {
+ this.input = input;
+ }
+
+ public String getOutput() {
+ return output;
+ }
+
+ public void setOutput(String output) {
+ this.output = output;
+ }
}
From e7bbe3901a85813162158990479f3102098c1731 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 22:50:16 +0400
Subject: [PATCH 10/14] refactoring controller file and new release recorded in
changelog file
---
CHANGELOG.md | 4 ++
.../controllers/OracleQuantController.java | 55 +++++++++++++------
2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3514ce..4db16c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## v0.0.3 - Controller refactoring
+- Fixed `OracleQuantController`: corrected endpoints to match REST spec (`/convert-measurements`, `@RequestParam`)
+- Added service injection, source IP capture, and proper HTTP responses
+
## v0.0.2 - Converter fixes and service layer
- Fixed conversion algorithm: corrected `checkInput` inversion, `backageCount` reset, and post-loop flush
- Added `OracleQuantService` with history CRUD operations
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
index 7d6494b..efba91f 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
@@ -1,35 +1,58 @@
package com.oraclequantapi.oraclequantapi.controllers;
+import com.oraclequantapi.oraclequantapi.models.OracleQuantRecord;
+import com.oraclequantapi.oraclequantapi.services.OracleQuantService;
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
-@RequestMapping(path = "/OracleQuant")
+@RequestMapping(path = "/convert-measurements")
public class OracleQuantController {
- @GetMapping(path = "/Convert")
- public List Convert(@PathVariable String input) {
- return null;
+ private final OracleQuantService service;
+
+ public OracleQuantController(OracleQuantService service) {
+ this.service = service;
+ }
+
+ @GetMapping
+ public ResponseEntity> convert(@RequestParam("input") String input,
+ HttpServletRequest request) {
+ List result = service.convertMeasurements(input, request.getRemoteAddr());
+ return ResponseEntity.ok(result);
+ }
+
+ @GetMapping("/history")
+ public ResponseEntity> getAllHistory() {
+ return ResponseEntity.ok(service.getAllHistory());
}
- @GetMapping(path = "/Fetch")
- public List fetch(@PathVariable String input) {
- return null;
+ @GetMapping("/history/{id}")
+ public ResponseEntity getHistoryById(@PathVariable Integer id) {
+ return service.getHistoryById(id)
+ .map(ResponseEntity::ok)
+ .orElse(ResponseEntity.notFound().build());
}
- @GetMapping(path = "/FetchAll")
- public List fetchAll() {
- return null;
+ @PutMapping("/history/{id}")
+ public ResponseEntity updateHistory(@PathVariable Integer id,
+ @RequestBody OracleQuantRecord record) {
+ OracleQuantRecord updated = service.updateHistory(id, record);
+ return ResponseEntity.ok(updated);
}
- @PutMapping(path = "/Update")
- public List Update(@PathVariable String input) {
- return null;
+ @DeleteMapping("/history")
+ public ResponseEntity clearHistory() {
+ service.clearHistory();
+ return ResponseEntity.noContent().build();
}
- @DeleteMapping(path = "/Delete")
- public List delete(@PathVariable String input) {
- return null;
+ @DeleteMapping("/history/{id}")
+ public ResponseEntity deleteHistory(@PathVariable Integer id) {
+ service.deleteHistoryById(id);
+ return ResponseEntity.noContent().build();
}
}
From 044e40a6a7aeac53790e2a4dd3fdad1d35803f81 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 23:03:23 +0400
Subject: [PATCH 11/14] prepare logback-spring.xml for logging feature and
implement necessary logic in related files
---
CHANGELOG.md | 4 +++
.../controllers/OracleQuantController.java | 31 ++++++++++++++++---
.../oraclequantapi/services/Converter.java | 26 +++++++++++++---
.../services/OracleQuantService.java | 22 +++++++++++--
src/main/resources/logback-spring.xml | 24 ++++++++++++++
5 files changed, 97 insertions(+), 10 deletions(-)
create mode 100644 src/main/resources/logback-spring.xml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4db16c1..9c2d244 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## v0.0.4 - Logging implementation
+- Added `logback-spring.xml` with console and rolling file appender (7-day retention)
+- Added SLF4J log statements to Controller, Service, and Converter
+
## v0.0.3 - Controller refactoring
- Fixed `OracleQuantController`: corrected endpoints to match REST spec (`/convert-measurements`, `@RequestParam`)
- Added service injection, source IP capture, and proper HTTP responses
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
index efba91f..b07a68b 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
@@ -3,6 +3,8 @@
import com.oraclequantapi.oraclequantapi.models.OracleQuantRecord;
import com.oraclequantapi.oraclequantapi.services.OracleQuantService;
import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -12,6 +14,8 @@
@RequestMapping(path = "/convert-measurements")
public class OracleQuantController {
+ private static final Logger log = LoggerFactory.getLogger(OracleQuantController.class);
+
private final OracleQuantService service;
public OracleQuantController(OracleQuantService service) {
@@ -21,38 +25,57 @@ public OracleQuantController(OracleQuantService service) {
@GetMapping
public ResponseEntity> convert(@RequestParam("input") String input,
HttpServletRequest request) {
- List result = service.convertMeasurements(input, request.getRemoteAddr());
+ String sourceIp = request.getRemoteAddr();
+ log.info("Conversion request - input: \"{}\", source IP: {}", input, sourceIp);
+ List result = service.convertMeasurements(input, sourceIp);
+ log.info("Conversion result - input: \"{}\", output: {}", input, result);
return ResponseEntity.ok(result);
}
@GetMapping("/history")
public ResponseEntity> getAllHistory() {
- return ResponseEntity.ok(service.getAllHistory());
+ log.info("Fetching all history records");
+ List records = service.getAllHistory();
+ log.info("Fetched {} history records", records.size());
+ return ResponseEntity.ok(records);
}
@GetMapping("/history/{id}")
public ResponseEntity getHistoryById(@PathVariable Integer id) {
+ log.info("Fetching history record by id: {}", id);
return service.getHistoryById(id)
- .map(ResponseEntity::ok)
- .orElse(ResponseEntity.notFound().build());
+ .map(record -> {
+ log.info("Found history record: {}", id);
+ return ResponseEntity.ok(record);
+ })
+ .orElseGet(() -> {
+ log.warn("History record not found: {}", id);
+ return ResponseEntity.notFound().build();
+ });
}
@PutMapping("/history/{id}")
public ResponseEntity updateHistory(@PathVariable Integer id,
@RequestBody OracleQuantRecord record) {
+ log.info("Updating history record: {}", id);
OracleQuantRecord updated = service.updateHistory(id, record);
+ log.info("Updated history record: {}", id);
return ResponseEntity.ok(updated);
}
@DeleteMapping("/history")
public ResponseEntity clearHistory() {
+ log.info("Clearing all history records");
service.clearHistory();
+ log.info("All history records cleared");
return ResponseEntity.noContent().build();
}
@DeleteMapping("/history/{id}")
public ResponseEntity deleteHistory(@PathVariable Integer id) {
+ log.info("Deleting history record: {}", id);
service.deleteHistoryById(id);
+ log.info("Deleted history record: {}", id);
return ResponseEntity.noContent().build();
}
}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
index e38f4d5..ec65d93 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/Converter.java
@@ -1,5 +1,7 @@
package com.oraclequantapi.oraclequantapi.services;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@@ -9,19 +11,27 @@
@Service
public class Converter {
+ private static final Logger log = LoggerFactory.getLogger(Converter.class);
+
public Converter() {
}
public List Convert(String input) {
+ log.debug("Starting conversion for input: \"{}\"", input);
String input1 = input.trim().toLowerCase();
String[] inputArray = input1.split("");
boolean checked = checkInput(inputArray);
if (!checked) {
+ log.warn("Invalid input: \"{}\"", input);
return null;
}
List list = valueToInt(inputArray);
+ log.debug("Value-to-int result: {}", list);
+
list = backageSize(list);
+ log.debug("Packaging result: {}", list);
+
return list;
}
@@ -43,18 +53,23 @@ public List backageSize(List valuesList) {
for (Integer integer : valuesList) {
if (backageCount == 0) {
backageCount = integer;
+ log.trace("Package count: {}", backageCount);
} else {
size += integer;
count++;
+ log.trace("Accumulated value: {}, running size: {}, count: {}/{}",
+ integer, size, count, backageCount);
}
if (backageCount == count) {
- backageSizeList.add(size);
- count = 0;
- size = 0;
- backageCount = 0;
+ backageSizeList.add(size);
+ log.trace("Package complete: sum={}", size);
+ count = 0;
+ size = 0;
+ backageCount = 0;
}
}
if (count > 0) {
+ log.trace("Adding partial package: sum={}", size);
backageSizeList.add(size);
}
return backageSizeList;
@@ -76,7 +91,10 @@ public List valueToInt(String[] inputs) {
if (!inputs[i].equals("z") || i == inputs.length -1) {
valueList.add(value);
+ log.trace("Decoded char '{}' -> accumulated value: {}", inputs[i], value);
value = 0;
+ } else {
+ log.trace("Char 'z' encountered, accumulating (total: {})", value);
}
}
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
index 143b246..dc07817 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/OracleQuantService.java
@@ -2,6 +2,8 @@
import com.oraclequantapi.oraclequantapi.models.OracleQuantRecord;
import com.oraclequantapi.oraclequantapi.repositories.OracleQuantRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@@ -11,6 +13,8 @@
@Service
public class OracleQuantService {
+ private static final Logger log = LoggerFactory.getLogger(OracleQuantService.class);
+
private final Converter converter;
private final OracleQuantRepository repository;
@@ -20,6 +24,7 @@ public OracleQuantService(Converter converter, OracleQuantRepository repository)
}
public List convertMeasurements(String input, String sourceIp) {
+ log.debug("Converting measurement - input: \"{}\", source IP: {}", input, sourceIp);
List result = converter.Convert(input);
OracleQuantRecord record = new OracleQuantRecord();
@@ -28,32 +33,45 @@ public List convertMeasurements(String input, String sourceIp) {
record.setInput(input);
record.setOutput(result != null ? result.toString() : null);
repository.save(record);
+ log.debug("Saved conversion history record for input: \"{}\", output: {}", input, result);
return result;
}
public List getAllHistory() {
+ log.debug("Fetching all history records");
return repository.findAll();
}
public Optional getHistoryById(Integer id) {
+ log.debug("Fetching history record by id: {}", id);
return repository.findById(id);
}
public OracleQuantRecord updateHistory(Integer id, OracleQuantRecord updated) {
+ log.debug("Updating history record: {}", id);
OracleQuantRecord record = repository.findById(id)
- .orElseThrow(() -> new RuntimeException("Record not found: " + id));
+ .orElseThrow(() -> {
+ log.error("Record not found for update: {}", id);
+ return new RuntimeException("Record not found: " + id);
+ });
record.setInput(updated.getInput());
record.setOutput(updated.getOutput());
record.setSourceIpAddress(updated.getSourceIpAddress());
- return repository.save(record);
+ OracleQuantRecord saved = repository.save(record);
+ log.debug("Updated history record: {}", id);
+ return saved;
}
public void clearHistory() {
+ log.debug("Clearing all history records");
repository.deleteAll();
+ log.debug("All history records cleared");
}
public void deleteHistoryById(Integer id) {
+ log.debug("Deleting history record: {}", id);
repository.deleteById(id);
+ log.debug("Deleted history record: {}", id);
}
}
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..1863a84
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+ logs/oraclequantapi.log
+
+ logs/oraclequantapi.%d{yyyy-MM-dd}.log
+ 7
+
+
+ %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
From 364626829bed3d6087a99ef7e5a9fb3e32ee406c Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 23:33:28 +0400
Subject: [PATCH 12/14] write README.md file
---
README.md | 207 ++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 146 insertions(+), 61 deletions(-)
diff --git a/README.md b/README.md
index b1cccfd..28cd420 100644
--- a/README.md
+++ b/README.md
@@ -1,61 +1,146 @@
-## Submission Instructions
-
-To submit your Oracle JAVA Spring Boot Maven project as a solution, please follow these steps:
-
-### Step 1: Install git on your PC
-- Install "git" as shown in this tutorial: [How to install git](https://youtu.be/iYkLrXobBbA?si=_l0haibv_X9NpIjJ)
-- Open command prompt and run
- ```bash
- git version
- ```
-- If you see the version, then git is successfully installed.
-
-### Step 2: Fork the Repository
-- Navigate to [this repository](https://github.com/CodelineAtyab/oraclequantapi) provided by Codeline.
-- Click on the "Fork" button at the top-right corner of the page to create a copy of the repository under your own GitHub account.
-
-### Step 3: Clone the Forked Repository
-- Open your terminal or command prompt.
-- Clone the forked repository to your local machine using the following command:
- ```bash
- git clone https://github.com/your-username/repo-name.git
- ```
-
-### Step 4: Create a new branch
-- Navigate to the cloned repository directory
- ```bash
- cd repo-name
- ```
-- Create a new branch for your code submissions (Replace your-name with your name in your-name-submission-branch):
- ```bash
- git checkout -b your-name-submission-branch
- ```
-
-
-### Step 5: Add Your Code
-- Implement the API
-
-### Step 6: Commit your changes
-- Run the following commands in order to commit your changes:
- ```bash
- git add *
- git commit -m "Meaningful commit message here"
- ```
-
-### Step 7: Push Your Branch to GitHub
-- Run the following commands to upload the changes to the forked github repository (Replace your-name with your name in your-name-submission-branch):
- ```bash
- git push origin your-name-submission-branch
- ```
-
-### Step 8: Create a Pull Request
-- Go to your forked repository on GitHub.
-- You should see a prompt to create a pull request. Click on "Compare & pull request".
-- Provide a title and description for your pull request, then click "Create pull request".
-
-### Step 9: Notify Codeline
-- Notify on slack that you have created a PR for your solution.
-
-## Note: If you face any issues in the process above, Please do the following:
-- Watch [this youtube tutorial](https://www.youtube.com/watch?v=a_FLqX3vGR4)
-- Contact Ikhlas or Atyab.
+# OracleQuant ERP - Package Measurement Conversion API
+
+A REST API for converting measurement input strings into package totals, built with **Java 17**, **Spring Boot**, **JPA**, and **Oracle XE**.
+
+---
+
+## Prerequisites
+
+- Oracle OpenJDK 17
+- Maven (or use the included `mvnw` wrapper)
+- Oracle XE database (21c+)
+
+---
+
+## Build
+
+```bash
+./mvnw clean package
+```
+
+Produces `target/oraclequantapi-0.0.1-SNAPSHOT.jar`.
+
+---
+
+## Database Configuration
+
+Edit `src/main/resources/application.properties`:
+
+```properties
+spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1
+spring.datasource.username=your_user
+spring.datasource.password=your_password
+spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
+
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.database-platform=org.hibernate.dialect.OracleDialect
+```
+
+Tables are created automatically via `ddl-auto=update`.
+
+---
+
+## Run
+
+```bash
+java -jar target/oraclequantapi-0.0.1-SNAPSHOT.jar
+```
+
+The API starts at `http://localhost:8080`.
+
+---
+
+## API Endpoints
+
+### Convert measurements
+
+```
+GET /convert-measurements?input={string}
+```
+
+**Response**: `200 OK` with JSON array of package totals.
+
+| Request | Response |
+|---|---|
+| `?input=aa` | `[1]` |
+| `?input=abbcc` | `[2, 6]` |
+| `?input=dz_a_aazzaaa` | `[28, 53, 1]` |
+| `?input=a_` | `[0]` |
+| `?input=abcdabcdab` | `[2, 7, 7]` |
+| `?input=abcdabcdab_` | `[2, 7, 7, 0]` |
+
+### History
+
+| Method | Endpoint | Description |
+|---|---|---|
+| GET | `/convert-measurements/history` | List all records |
+| GET | `/convert-measurements/history/{id}` | Get record by ID |
+| PUT | `/convert-measurements/history/{id}` | Update record |
+| DELETE | `/convert-measurements/history` | Clear all history |
+| DELETE | `/convert-measurements/history/{id}` | Delete record by ID |
+
+Each history record contains: `id`, `timestamp`, `source_ip_address`, `input`, `output`.
+
+---
+
+## Deploy on Oracle Linux
+
+### 1. Transfer the JAR
+
+```bash
+scp target/oraclequantapi-0.0.1-SNAPSHOT.jar oracle@your-vm-ip:/home/oracle/
+```
+
+### 2. SSH into the VM
+
+```bash
+ssh oracle@your-vm-ip
+```
+
+### 3. Install Java (if not present)
+
+```bash
+sudo dnf install java-17-openjdk-devel
+```
+
+### 4. Run as a service (optional)
+
+```bash
+sudo tee /etc/systemd/system/oraclequantapi.service < 26: chain `z` characters (each adds 26), terminated by a non-`z` letter
+- Each package: first number = count of values, then sum of that many values
+
+---
+
+## Logging
+
+Logs are written to `logs/oraclequantapi.YYYY-MM-DD.log` and rotated daily, retained for 7 days.
From 0f14e24e66b6c92c51bc94dc96ea600a15d858c1 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Sun, 24 May 2026 23:42:48 +0400
Subject: [PATCH 13/14] minor quality improvement on controller and add
converter logic test
---
CHANGELOG.md | 4 ++
.../controllers/OracleQuantController.java | 4 ++
.../oraclequantapi/ConverterTest.java | 68 +++++++++++++++++++
3 files changed, 76 insertions(+)
create mode 100644 src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c2d244..d4daa2b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## v0.0.5 - Null safety and tests
+- Fixed controller: invalid input now returns 400 Bad Request instead of 200 with null body
+- Added `ConverterTest` with all 8 spec examples and invalid input tests
+
## v0.0.4 - Logging implementation
- Added `logback-spring.xml` with console and rolling file appender (7-day retention)
- Added SLF4J log statements to Controller, Service, and Converter
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
index b07a68b..ff67d80 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/OracleQuantController.java
@@ -28,6 +28,10 @@ public ResponseEntity> convert(@RequestParam("input") String input
String sourceIp = request.getRemoteAddr();
log.info("Conversion request - input: \"{}\", source IP: {}", input, sourceIp);
List result = service.convertMeasurements(input, sourceIp);
+ if (result == null) {
+ log.warn("Invalid input, returning 400 - input: \"{}\"", input);
+ return ResponseEntity.badRequest().build();
+ }
log.info("Conversion result - input: \"{}\", output: {}", input, result);
return ResponseEntity.ok(result);
}
diff --git a/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java b/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java
new file mode 100644
index 0000000..d197c71
--- /dev/null
+++ b/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java
@@ -0,0 +1,68 @@
+package com.oraclequantapi.oraclequantapi;
+
+import com.oraclequantapi.oraclequantapi.services.Converter;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+class ConverterTest {
+
+ private Converter converter;
+
+ @BeforeEach
+ void setUp() {
+ converter = new Converter();
+ }
+
+ @Test
+ void testAa() {
+ assertEquals(List.of(1), converter.Convert("aa"));
+ }
+
+ @Test
+ void testAbbcc() {
+ assertEquals(List.of(2, 6), converter.Convert("abbcc"));
+ }
+
+ @Test
+ void testDz_a_aazzaaa() {
+ assertEquals(List.of(28, 53, 1), converter.Convert("dz_a_aazzaaa"));
+ }
+
+ @Test
+ void testA_() {
+ assertEquals(List.of(0), converter.Convert("a_"));
+ }
+
+ @Test
+ void testAbcdabcdab() {
+ assertEquals(List.of(2, 7, 7), converter.Convert("abcdabcdab"));
+ }
+
+ @Test
+ void testAbcdabcdab_() {
+ assertEquals(List.of(2, 7, 7, 0), converter.Convert("abcdabcdab_"));
+ }
+
+ @Test
+ void testZdaaaaaaaabaaaaaaaabaaaaaaaabbaa() {
+ assertEquals(List.of(34), converter.Convert("zdaaaaaaaabaaaaaaaabaaaaaaaabbaa"));
+ }
+
+ @Test
+ void testZa_a_a_a_a_a_a_a_a_a_a_a_a_azaaa() {
+ assertEquals(List.of(40, 1), converter.Convert("za_a_a_a_a_a_a_a_a_a_a_a_a_azaaa"));
+ }
+
+ @Test
+ void testInvalidInputReturnsNull() {
+ assertNull(converter.Convert("AA"));
+ assertNull(converter.Convert("123"));
+ assertNull(converter.Convert("a b"));
+ assertNull(converter.Convert(""));
+ }
+}
From 4c026fd24415cae076b74933d29d78046ec8eb25 Mon Sep 17 00:00:00 2001
From: Ya'Rab Al-Mamari
Date: Mon, 25 May 2026 09:53:49 +0400
Subject: [PATCH 14/14] bug fix
---
CHANGELOG.md | 5 +
logs/oraclequantapi.2026-05-24.log | 207 ++++++++++++++++++
logs/oraclequantapi.log | 27 +++
.../models/OracleQuantRecord.java | 4 +-
.../oraclequantapi/ConverterTest.java | 1 -
5 files changed, 241 insertions(+), 3 deletions(-)
create mode 100644 logs/oraclequantapi.2026-05-24.log
create mode 100644 logs/oraclequantapi.log
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4daa2b..7eb6186 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## v0.0.6 - Bug fixes
+- Fixed test: removed "AA" from invalid input test (converter normalizes to lowercase)
+- Fixed Oracle compatibility: changed `TEXT` column type to `@Lob` (maps to CLOB)
+- All 10 tests pass
+
## v0.0.5 - Null safety and tests
- Fixed controller: invalid input now returns 400 Bad Request instead of 200 with null body
- Added `ConverterTest` with all 8 spec examples and invalid input tests
diff --git a/logs/oraclequantapi.2026-05-24.log b/logs/oraclequantapi.2026-05-24.log
new file mode 100644
index 0000000..749a5db
--- /dev/null
+++ b/logs/oraclequantapi.2026-05-24.log
@@ -0,0 +1,207 @@
+2026-05-24 23:45:10 [main] INFO c.o.o.OraclequantapiApplicationTests - Starting OraclequantapiApplicationTests using Java 21.0.7 with PID 21508 (started by USER in C:\Users\USER\Desktop\CodeLine\oraclequantapi)
+2026-05-24 23:45:10 [main] INFO c.o.o.OraclequantapiApplicationTests - No active profile set, falling back to 1 default profile: "default"
+2026-05-24 23:45:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2026-05-24 23:45:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 104 ms. Found 1 JPA repository interface.
+2026-05-24 23:45:13 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
+2026-05-24 23:45:13 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.6.49.Final
+2026-05-24 23:45:14 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
+2026-05-24 23:45:14 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
+2026-05-24 23:45:14 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2026-05-24 23:45:16 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection oracle.jdbc.driver.T4CConnection@9f2376f
+2026-05-24 23:45:16 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
+2026-05-24 23:45:16 [main] WARN org.hibernate.orm.deprecation - HHH90000025: OracleDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2026-05-24 23:45:17 [main] INFO o.hibernate.orm.connections.pooling - HHH10001005: Database info:
+ Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+ Database driver: undefined/unknown
+ Database version: 21.3
+ Autocommit mode: undefined/unknown
+ Isolation level: undefined/unknown
+ Minimum pool size: undefined/unknown
+ Maximum pool size: undefined/unknown
+2026-05-24 23:45:19 [main] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2026-05-24 23:45:24 [main] WARN o.h.t.s.i.ExceptionHandlerLoggedImpl - GenerationTarget encountered exception accepting command : Error executing DDL "create table conversion_history (id number(10,0) generated by default as identity, input TEXT, output TEXT, source_ip_address varchar2(255 char), timestamp timestamp(6), primary key (id))" via JDBC [ORA-00902: invalid datatype
+
+https://docs.oracle.com/error-help/db/ora-00902/]
+org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table conversion_history (id number(10,0) generated by default as identity, input TEXT, output TEXT, source_ip_address varchar2(255 char), timestamp timestamp(6), primary key (id))" via JDBC [ORA-00902: invalid datatype
+
+https://docs.oracle.com/error-help/db/ora-00902/]
+ at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:94)
+ at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:576)
+ at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:516)
+ at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.createTable(AbstractSchemaMigrator.java:316)
+ at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:80)
+ at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:233)
+ at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:112)
+ at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:280)
+ at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:144)
+ at java.base/java.util.HashMap.forEach(HashMap.java:1429)
+ at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:141)
+ at org.hibernate.boot.internal.SessionFactoryObserverForSchemaExport.sessionFactoryCreated(SessionFactoryObserverForSchemaExport.java:37)
+ at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
+ at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:324)
+ at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:463)
+ at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1517)
+ at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66)
+ at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:388)
+ at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:419)
+ at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:400)
+ at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:364)
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1873)
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1822)
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607)
+ at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
+ at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
+ at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
+ at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
+ at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
+ at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:974)
+ at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:628)
+ at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
+ at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
+ at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
+ at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:151)
+ at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
+ at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
+ at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1461)
+ at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:590)
+ at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:151)
+ at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:110)
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
+ at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
+ at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
+ at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:200)
+ at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:139)
+ at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
+ at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:159)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:383)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:388)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:382)
+ at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
+ at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
+ at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
+ at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
+ at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
+ at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
+ at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
+ at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
+ at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
+ at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
+ at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:382)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:293)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:292)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:281)
+ at java.base/java.util.Optional.orElseGet(Optional.java:364)
+ at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:280)
+ at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:27)
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:112)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:111)
+ at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:69)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:128)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:128)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
+ at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146)
+ at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100)
+ at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:160)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:146)
+ at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:144)
+ at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:143)
+ at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:100)
+ at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
+ at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
+ at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
+ at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:201)
+ at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:170)
+ at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:94)
+ at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:59)
+ at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:142)
+ at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:58)
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:103)
+ at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:85)
+ at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
+ at org.junit.platform.launcher.core.InterceptingLauncher.lambda$execute$1(InterceptingLauncher.java:39)
+ at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
+ at org.junit.platform.launcher.core.InterceptingLauncher.execute(InterceptingLauncher.java:38)
+ at org.junit.platform.launcher.core.DelegatingLauncher.execute(DelegatingLauncher.java:47)
+ at org.apache.maven.surefire.junitplatform.LauncherAdapter.executeWithoutCancellationToken(LauncherAdapter.java:60)
+ at org.apache.maven.surefire.junitplatform.LauncherAdapter.execute(LauncherAdapter.java:52)
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:203)
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:168)
+ at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:136)
+ at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
+ at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
+ at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
+ at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
+Caused by: java.sql.SQLSyntaxErrorException: ORA-00902: invalid datatype
+
+https://docs.oracle.com/error-help/db/ora-00902/
+ at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:715)
+ at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:615)
+ at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1372)
+ at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:969)
+ at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:237)
+ at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:524)
+ at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:192)
+ at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1401)
+ at oracle.jdbc.driver.OracleStatement.executeSQLStatement(OracleStatement.java:2009)
+ at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1622)
+ at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:2687)
+ at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:2636)
+ at oracle.jdbc.driver.OracleStatementWrapper.execute(OracleStatementWrapper.java:337)
+ at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
+ at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
+ at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:80)
+ ... 122 common frames omitted
+Caused by: Error : 902, Position : 89, SQL = create table conversion_history (id number(10,0) generated by default as identity, input TEXT, output TEXT, source_ip_address varchar2(255 char), timestamp timestamp(6), primary key (id)), Original SQL = create table conversion_history (id number(10,0) generated by default as identity, input TEXT, output TEXT, source_ip_address varchar2(255 char), timestamp timestamp(6), primary key (id)), Error Message = ORA-00902: invalid datatype
+
+ at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:723)
+ ... 137 common frames omitted
+2026-05-24 23:45:24 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
+2026-05-24 23:45:25 [main] WARN o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
+2026-05-24 23:45:25 [main] INFO c.o.o.OraclequantapiApplicationTests - Started OraclequantapiApplicationTests in 16.298 seconds (process running for 18.387)
+2026-05-24 23:45:27 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
+2026-05-24 23:45:27 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
+2026-05-24 23:45:27 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
+2026-05-24 23:46:07 [main] INFO c.o.o.OraclequantapiApplicationTests - Starting OraclequantapiApplicationTests using Java 21.0.7 with PID 1448 (started by USER in C:\Users\USER\Desktop\CodeLine\oraclequantapi)
+2026-05-24 23:46:07 [main] INFO c.o.o.OraclequantapiApplicationTests - No active profile set, falling back to 1 default profile: "default"
+2026-05-24 23:46:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2026-05-24 23:46:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 106 ms. Found 1 JPA repository interface.
+2026-05-24 23:46:10 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
+2026-05-24 23:46:10 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.6.49.Final
+2026-05-24 23:46:10 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
+2026-05-24 23:46:11 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
+2026-05-24 23:46:11 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2026-05-24 23:46:12 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection oracle.jdbc.driver.T4CConnection@3b33fff9
+2026-05-24 23:46:12 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
+2026-05-24 23:46:13 [main] WARN org.hibernate.orm.deprecation - HHH90000025: OracleDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2026-05-24 23:46:13 [main] INFO o.hibernate.orm.connections.pooling - HHH10001005: Database info:
+ Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+ Database driver: undefined/unknown
+ Database version: 21.3
+ Autocommit mode: undefined/unknown
+ Isolation level: undefined/unknown
+ Minimum pool size: undefined/unknown
+ Maximum pool size: undefined/unknown
+2026-05-24 23:46:15 [main] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2026-05-24 23:46:19 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
+2026-05-24 23:46:19 [main] WARN o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
+2026-05-24 23:46:20 [main] INFO c.o.o.OraclequantapiApplicationTests - Started OraclequantapiApplicationTests in 14.185 seconds (process running for 16.35)
+2026-05-24 23:46:21 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
+2026-05-24 23:46:21 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
+2026-05-24 23:46:21 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
diff --git a/logs/oraclequantapi.log b/logs/oraclequantapi.log
new file mode 100644
index 0000000..052c880
--- /dev/null
+++ b/logs/oraclequantapi.log
@@ -0,0 +1,27 @@
+2026-05-25 09:51:07 [main] INFO c.o.o.OraclequantapiApplicationTests - Starting OraclequantapiApplicationTests using Java 21.0.7 with PID 16144 (started by USER in C:\Users\USER\Desktop\CodeLine\oraclequantapi)
+2026-05-25 09:51:07 [main] INFO c.o.o.OraclequantapiApplicationTests - No active profile set, falling back to 1 default profile: "default"
+2026-05-25 09:51:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2026-05-25 09:51:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 115 ms. Found 1 JPA repository interface.
+2026-05-25 09:51:10 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
+2026-05-25 09:51:10 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.6.49.Final
+2026-05-25 09:51:10 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
+2026-05-25 09:51:11 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
+2026-05-25 09:51:11 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2026-05-25 09:51:13 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection oracle.jdbc.driver.T4CConnection@7e1a9173
+2026-05-25 09:51:13 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
+2026-05-25 09:51:13 [main] WARN org.hibernate.orm.deprecation - HHH90000025: OracleDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2026-05-25 09:51:14 [main] INFO o.hibernate.orm.connections.pooling - HHH10001005: Database info:
+ Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+ Database driver: undefined/unknown
+ Database version: 21.3
+ Autocommit mode: undefined/unknown
+ Isolation level: undefined/unknown
+ Minimum pool size: undefined/unknown
+ Maximum pool size: undefined/unknown
+2026-05-25 09:51:16 [main] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2026-05-25 09:51:22 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
+2026-05-25 09:51:23 [main] WARN o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
+2026-05-25 09:51:24 [main] INFO c.o.o.OraclequantapiApplicationTests - Started OraclequantapiApplicationTests in 18.518 seconds (process running for 21.467)
+2026-05-25 09:51:25 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
+2026-05-25 09:51:25 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
+2026-05-25 09:51:25 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
index 17637f9..132df1a 100644
--- a/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
+++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/OracleQuantRecord.java
@@ -16,10 +16,10 @@ public class OracleQuantRecord {
@Column(name = "source_ip_address")
private String sourceIpAddress;
- @Column(columnDefinition = "TEXT")
+ @Lob
private String input;
- @Column(columnDefinition = "TEXT")
+ @Lob
private String output;
public OracleQuantRecord() {}
diff --git a/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java b/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java
index d197c71..bba3bc9 100644
--- a/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java
+++ b/src/test/java/com/oraclequantapi/oraclequantapi/ConverterTest.java
@@ -60,7 +60,6 @@ void testZa_a_a_a_a_a_a_a_a_a_a_a_a_azaaa() {
@Test
void testInvalidInputReturnsNull() {
- assertNull(converter.Convert("AA"));
assertNull(converter.Convert("123"));
assertNull(converter.Convert("a b"));
assertNull(converter.Convert(""));