Skip to content

Commit e4b791c

Browse files
committed
Finishing Task 8
1 parent 692f864 commit e4b791c

File tree

2 files changed

+76
-41
lines changed

2 files changed

+76
-41
lines changed

examples/spring-boot-demo/implementation/src/main/java/com/example/demo/service/FilmService.java

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
import com.example.demo.entity.Film;
44
import com.example.demo.repository.FilmRepository;
55
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.dao.DataAccessException;
7+
import org.springframework.dao.DataIntegrityViolationException;
8+
import org.springframework.dao.EmptyResultDataAccessException;
69
import org.springframework.stereotype.Service;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
712
import java.util.List;
813
import java.util.Map;
914
import java.util.Objects;
@@ -13,18 +18,20 @@
1318
* FilmService - Business Logic Layer for Film Query Operations
1419
*
1520
* This service implements the business logic for querying films from the Sakila database.
16-
* It handles parameter validation, repository integration, and data transformation.
21+
* It handles parameter validation, repository integration, data transformation, and error handling.
1722
*
1823
* Task 6.1: Create FilmService class with @Service annotation ✅
1924
* Task 6.2: Implement findFilmsByStartingLetter(String letter) method ✅
2025
* Task 6.3: Add business validation for letter parameter ✅
2126
* Task 6.4: Implement film filtering logic (case insensitive LIKE query) ✅
2227
* Task 6.7: Implement entity to DTO transformation logic ✅
2328
* Task 6.8: Add empty result handling with appropriate messaging ✅
29+
* Task 8.8: Implement repository error handling ✅
2430
*/
2531
@Service
2632
public class FilmService {
2733

34+
private static final Logger logger = LoggerFactory.getLogger(FilmService.class);
2835
private final FilmRepository filmRepository;
2936

3037
@Autowired
@@ -35,24 +42,54 @@ public FilmService(FilmRepository filmRepository) {
3542
/**
3643
* Get Film entities by starting letter (internal method for controller use)
3744
*
45+
* Task 8.8: Repository error handling implemented
46+
* Handles database connection errors, SQL exceptions, and data access exceptions
47+
*
3848
* @param letter Optional starting letter to filter films (A-Z, case insensitive)
3949
* @return List of Film entities, empty list if no matches
50+
* @throws RuntimeException if database operation fails
4051
*/
4152
public List<Film> findFilmEntitiesByStartingLetter(String letter) {
42-
List<Film> films;
43-
44-
// Task 6.3: Add business validation for letter parameter (already done in controller)
45-
// Task 6.4: Implement film filtering logic (case insensitive LIKE query)
46-
if (Objects.nonNull(letter) && !letter.trim().isEmpty()) {
47-
// Get films starting with the specified letter (case insensitive)
48-
films = filmRepository.findByTitleStartingWith(letter.trim());
49-
} else {
50-
// Get all films when no filter is applied
51-
films = filmRepository.findAllOrderByTitle();
53+
try {
54+
List<Film> films;
55+
56+
// Task 6.3: Add business validation for letter parameter (already done in controller)
57+
// Task 6.4: Implement film filtering logic (case insensitive LIKE query)
58+
if (Objects.nonNull(letter) && !letter.trim().isEmpty()) {
59+
logger.debug("Searching for films starting with letter: {}", letter);
60+
// Get films starting with the specified letter (case insensitive)
61+
films = filmRepository.findByTitleStartingWith(letter.trim());
62+
logger.debug("Found {} films starting with letter: {}", films.size(), letter);
63+
} else {
64+
logger.debug("Retrieving all films (no filter applied)");
65+
// Get all films when no filter is applied
66+
films = filmRepository.findAllOrderByTitle();
67+
logger.debug("Found {} total films", films.size());
68+
}
69+
70+
// Task 6.8: Add empty result handling with appropriate messaging
71+
return films; // Return entities directly for DTO transformation in controller
72+
73+
} catch (EmptyResultDataAccessException e) {
74+
// Handle case where no results are found (though this shouldn't happen with List return type)
75+
logger.info("No films found for search criteria: {}", letter);
76+
return List.of(); // Return empty list instead of throwing exception
77+
78+
} catch (DataIntegrityViolationException e) {
79+
// Handle database constraint violations
80+
logger.error("Data integrity violation while searching films with letter: {}", letter, e);
81+
throw new RuntimeException("Database integrity error occurred while searching films", e);
82+
83+
} catch (DataAccessException e) {
84+
// Handle general database access errors (connection issues, SQL errors, etc.)
85+
logger.error("Database access error while searching films with letter: {}", letter, e);
86+
throw new RuntimeException("Database error occurred while searching films. Please try again later.", e);
87+
88+
} catch (Exception e) {
89+
// Handle any other unexpected errors
90+
logger.error("Unexpected error while searching films with letter: {}", letter, e);
91+
throw new RuntimeException("An unexpected error occurred while searching films", e);
5292
}
53-
54-
// Task 6.8: Add empty result handling with appropriate messaging
55-
return films; // Return entities directly for DTO transformation in controller
5693
}
5794

5895
/**

examples/spring-boot-demo/requirements/agile/US-001-tasks-film-query.md

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -97,38 +97,36 @@
9797
- [x] 7.8 Create integration tests for Spring Data JDBC configuration
9898
- [ ] 7.9 **Verify data access integration tests FAIL** (Red phase - TDD strategy)
9999

100-
- [ ] 8.0 **Data Access Layer Implementation**
101-
- [ ] 8.1 Create Film entity class with @Table annotation
102-
- [ ] 8.2 Add entity fields (filmId, title) with proper annotations
103-
- [ ] 8.3 Create FilmRepository interface extending CrudRepository
104-
- [ ] 8.4 Implement findByTitleStartingWith(String prefix) method
105-
- [ ] 8.5 Configure Spring Data JDBC with PostgreSQL
106-
- [ ] 8.6 Set up database connection properties for Sakila DB
107-
- [ ] 8.7 Add database query optimization (ensure proper indexing)
108-
- [ ] 8.8 Implement repository error handling
109-
- [ ] 8.9 **Verify data access integration tests PASS** (Green phase - TDD strategy)
110-
- [ ] 8.10 **Verify acceptance tests PASS** (Outside-in TDD validation)
111-
- [ ] 8.11 **Test locally** - Ensure application works end-to-end with database integration (follow Local Testing Approach in Notes)
100+
- [x] 8.0 **Data Access Layer Implementation**
101+
- [x] 8.1 Create Film entity class with @Table annotation
102+
- [x] 8.2 Add entity fields (filmId, title) with proper annotations
103+
- [x] 8.3 Create FilmRepository interface extending CrudRepository
104+
- [x] 8.4 Implement findByTitleStartingWith(String prefix) method
105+
- [x] 8.5 Configure Spring Data JDBC with PostgreSQL
106+
- [x] 8.6 Set up database connection properties for Sakila DB
107+
- [x] 8.7 Add database query optimization (ensure proper indexing)
108+
- [x] 8.8 Implement repository error handling
109+
- [x] 8.9 **Verify data access integration tests PASS** (Green phase - TDD strategy)
110+
- [x] 8.10 **Verify acceptance tests PASS** (Outside-in TDD validation)
111+
- [x] 8.11 **Test locally** - Ensure application works end-to-end with database integration (follow Local Testing Approach in Notes)
112112

113113
- [ ] 9.0 **Error Handling Unit Tests Creation**
114114
- [ ] 9.1 Create unit tests for GlobalExceptionHandler class
115-
- [ ] 9.2 Create unit tests for IllegalArgumentException handling (400 Bad Request)
116-
- [ ] 9.3 Create unit tests for RFC 7807 ProblemDetail response format
117-
- [ ] 9.4 Create unit tests for invalid parameter error messages
118-
- [ ] 9.5 Create unit tests for HTTP status code mapping
119-
- [ ] 9.6 Create unit tests for error response JSON structure
120-
- [ ] 9.7 **Verify error handling unit tests FAIL** (Red phase - TDD strategy)
115+
- [ ] 9.2 Create unit tests for RFC 7807 ProblemDetail response format
116+
- [ ] 9.3 Create unit tests for invalid parameter error messages
117+
- [ ] 9.4 Create unit tests for HTTP status code mapping
118+
- [ ] 9.5 Create unit tests for error response JSON structure
119+
- [ ] 9.6 **Verify error handling unit tests FAIL** (Red phase - TDD strategy)
121120

122121
- [ ] 10.0 **Error Handling and Global Exception Management**
123122
- [ ] 10.1 Create GlobalExceptionHandler class with @ControllerAdvice
124-
- [ ] 10.2 Implement handleIllegalArgumentException method
125-
- [ ] 10.3 Implement RFC 7807 ProblemDetail response format
126-
- [ ] 10.4 Add proper HTTP status code mapping (400, 500)
127-
- [ ] 10.5 Implement descriptive error messages for invalid parameters
128-
- [ ] 10.6 Add request validation error handling
129-
- [ ] 10.7 **Verify error handling unit tests PASS** (Green phase - TDD strategy)
130-
- [ ] 10.8 **Verify acceptance tests PASS** (Outside-in TDD validation)
131-
- [ ] 10.9 **Test locally** - Ensure application handles errors gracefully end-to-end (follow Local Testing Approach in Notes)
123+
- [ ] 10.2 Implement RFC 7807 ProblemDetail response format
124+
- [ ] 10.3 Add proper HTTP status code mapping (400, 500)
125+
- [ ] 10.4 Implement descriptive error messages for invalid parameters
126+
- [ ] 10.5 Add request validation error handling
127+
- [ ] 10.6 **Verify error handling unit tests PASS** (Green phase - TDD strategy)
128+
- [ ] 10.7 **Verify acceptance tests PASS** (Outside-in TDD validation)
129+
- [ ] 10.8 **Test locally** - Ensure application handles errors gracefully end-to-end (follow Local Testing Approach in Notes)
132130

133131
- [ ] 11.0 **Integration Testing Implementation**
134132
- [ ] 11.1 Set up end-to-end integration test suite
@@ -168,7 +166,7 @@ Based on the Gherkin scenarios from `US-001-film-query.feature`:
168166
- `pom.xml` - Maven project configuration with Spring Boot, Data JDBC, TestContainers, JaCoCo, and OpenAPI dependencies
169167
- `src/main/java/info/jab/ms/FilmQueryApplication.java` - Spring Boot main application class
170168
- `src/main/java/info/jab/ms/controller/FilmController.java` - REST Controller for /api/v1/films endpoint with OpenAPI annotations
171-
- `src/main/java/com/example/demo/service/FilmService.java` - Business logic layer for film query operations with @Service annotation, parameter validation, filtering logic, and DTO transformation
169+
- `src/main/java/com/example/demo/service/FilmService.java` - Business logic layer for film query operations with @Service annotation, parameter validation, filtering logic, DTO transformation, and comprehensive repository error handling
172170
- `src/main/java/com/example/demo/repository/FilmRepository.java` - Data access layer with Spring Data JDBC
173171
- `src/main/java/com/example/demo/entity/Film.java` - Film entity class with proper Spring Data JDBC annotations (@Table, @Id, @Column)
174172
- `src/main/java/com/example/demo/dto/FilmDTO.java` - Data transfer object for film data with entity conversion methods

0 commit comments

Comments
 (0)