Backend API for OBR Facturation System - Spring Boot 3.5 + Java 21
7.6K
This directory contains the complete backend implementation for Option 1: Custom Pagination Response that eliminates the Spring warning about unstable JSON structure.
/findall endpointYour backend is likely in a separate directory. Find it:
# Common locations:
d:\OBR\facturation\facturation\backend
d:\OBR\facturation\facturation\facturationbe
# Or similar
Copy the files from this BACKEND_IMPLEMENTATION folder to your backend project:
Your Backend Project Structure:
āāā src/
ā āāā main/
ā āāā java/
ā āāā com/obr/facturation/
ā āāā controller/
ā ā āāā InvoiceController.java ā COPY THIS
ā āāā service/
ā ā āāā InvoiceService.java ā COPY THIS
ā āāā repository/
ā ā āāā InvoiceRepository.java ā COPY THIS
ā āāā model/
ā āāā Invoice.java ā REFERENCE ONLY (adjust your existing model)
Open each file and update the package declaration at the top to match your project structure.
Example:
If your controller is in com.yourcompany.facturation.controller, change:
package com.obr.facturation.controller;
to:
package com.yourcompany.facturation.controller;
Update the import statements to match your project's package structure:
// OLD
import com.obr.facturation.model.Invoice;
import com.obr.facturation.service.InvoiceService;
// NEW (example)
import com.yourcompany.facturation.model.Invoice;
import com.yourcompany.facturation.service.InvoiceService;
The service file contains TODO comments for methods that depend on your specific implementation:
// TODO: Implement based on your InvoiceItem model
public List<?> findInvoiceItems(Long invoiceId) {
// Add your implementation here
}
Update these methods based on your existing code and database structure.
Ensure your pom.xml (Maven) or build.gradle (Gradle) has these dependencies:
Maven (pom.xml):
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Lombok (optional, for @Data annotations) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle (build.gradle):
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
If your Invoice.java entity is different, ensure it has these fields for pagination to work properly:
id (Long)taxPayerId (Long)userPosition (Integer)The entity should extend Serializable and use JPA annotations (@Entity, @Table, @Id, etc.)
For better performance with large datasets, add indexes on frequently queried columns:
SQL:
-- Add indexes for better pagination performance
CREATE INDEX idx_invoice_tax_payer_id ON invoice(tax_payer_id);
CREATE INDEX idx_invoice_user_position ON invoice(user_position);
CREATE INDEX idx_invoice_date ON invoice(invoice_date);
CREATE INDEX idx_invoice_type ON invoice(invoice_type);
CREATE INDEX idx_invoice_payment_type ON invoice(invoice_payment_type);
CREATE INDEX idx_invoice_number ON invoice(invoice_number);
-- Composite index for common filter combination
CREATE INDEX idx_invoice_taxpayer_position ON invoice(tax_payer_id, user_position);
# Maven
mvn clean install
# Gradle
gradle clean build
# Maven
mvn spring-boot:run
# Gradle
gradle bootRun
# Test 1: Get first page (10 items)
curl "http://localhost:8080/api/invoices/findall?page=0&size=10&sort=id,desc"
# Test 2: Get second page
curl "http://localhost:8080/api/invoices/findall?page=1&size=10&sort=id,desc"
# Test 3: With filters
curl "http://localhost:8080/api/invoices/findall?page=0&size=20&taxPayerId=123&userPosition=1&sort=invoiceDate,desc"
# Test 4: Larger page size
curl "http://localhost:8080/api/invoices/findall?page=0&size=50&sort=invoiceNumber,asc"
Your API should now return this stable JSON structure:
{
"content": [
{
"id": 1,
"invoiceNumber": "INV-001",
"invoiceType": "FN",
"invoiceDate": "2024-01-15T10:30:00",
"client": {
"id": 1,
"name": "Client Name"
},
"total": 5000,
"invoiceCurrency": "BIF",
"invoicePaymentType": "CASH",
...
}
// ... more invoices
],
"currentPage": 0,
"totalItems": 150,
"totalPages": 15,
"pageSize": 10,
"hasNext": true,
"hasPrevious": false,
"isFirst": true,
"isLast": false
}
/api/invoices/findall returns paginated dataSolution: Update the import statement to match your project's package structure.
Solution: Ensure InvoiceRepository extends JpaRepository<Invoice, Long>
Solution: Check that your Invoice entity has a field named taxPayerId or update the repository methods to match your field names.
Solution: Make sure you're returning the Map<String, Object> response structure, NOT the Page<Invoice> directly.
Solution:
curl http://localhost:8080/api/invoices/findall@CrossOrigin(origins = "*")Solution: Add database indexes (see Step 8)
Use proper page sizes:
Add indexes on sorted columns:
CREATE INDEX idx_invoice_date ON invoice(invoice_date DESC);
Avoid JOIN FETCH with pagination:
Use database-level pagination:
Monitor query performance:
# application.yml
spring:
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | Integer | No | 0 | Page number (0-indexed) |
size | Integer | No | 10 | Items per page (1-100) |
sort | String[] | No | id,desc | Sort format: "field,direction" |
taxPayerId | Long | No | - | Filter by tax payer ID |
userPosition | Integer | No | - | Filter by user position |
Sort Examples:
sort=id,desc - Sort by ID descendingsort=invoiceDate,asc - Sort by date ascendingsort=total,desc - Sort by total descendingsort=invoiceNumber,asc - Sort by invoice number ascendingExample Requests:
# Basic pagination
GET /api/invoices/findall?page=0&size=10
# With sorting
GET /api/invoices/findall?page=0&size=20&sort=invoiceDate,desc
# With filters
GET /api/invoices/findall?page=1&size=50&taxPayerId=123&userPosition=2
# Complex query
GET /api/invoices/findall?page=2&size=25&taxPayerId=123&userPosition=1&sort=total,desc
If you encounter issues:
You'll know it's working when:
ā
No Spring warning about unstable JSON structure in logs
ā
API returns stable JSON format with content and pagination metadata
ā
Frontend displays paginated invoice list
ā
Page navigation works smoothly
ā
Sorting updates the data correctly
ā
Filters apply without issues
ā
Performance is fast even with many invoices
Good luck with your implementation! š
Content type
Image
Digest
sha256:7ce95da30ā¦
Size
161.8 MB
Last updated
11 days ago
docker pull wilfriedpapt89/facturationbe