Skip to content

Commit 3519b60

Browse files
committed
Use builder defaults for response records and clean up annotations
Replace compact constructors in SuccessResponse and ErrorResponse with partial builder class declarations to provide proper defaults, and remove now-redundant .success() and .timestamp() calls from all builder sites. Use @with for DirectorStatisticsResult.averageRating to match the pattern in MoviesByYearResult. Expand wildcard lombok import in Movie.
1 parent 47328c6 commit 3519b60

7 files changed

Lines changed: 15 additions & 54 deletions

File tree

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/controller/MovieControllerImpl.java

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import io.swagger.v3.oas.annotations.Parameter;
1919
import io.swagger.v3.oas.annotations.tags.Tag;
2020
import jakarta.validation.Valid;
21-
import java.time.Instant;
2221
import java.util.List;
2322
import java.util.Map;
2423
import org.bson.Document;
@@ -103,10 +102,8 @@ public ResponseEntity<SuccessResponse<List<Movie>>> getAllMovies(
103102
String message = "Found " + movies.size() + " movies";
104103

105104
SuccessResponse<List<Movie>> response = SuccessResponse.<List<Movie>>builder()
106-
.success(true)
107105
.message(message)
108106
.data(movies)
109-
.timestamp(Instant.now().toString())
110107
.build();
111108

112109
return ResponseEntity.ok(response);
@@ -122,10 +119,8 @@ public ResponseEntity<SuccessResponse<List<String>>> getDistinctGenres() {
122119
List<String> genres = movieService.getDistinctGenres();
123120

124121
SuccessResponse<List<String>> response = SuccessResponse.<List<String>>builder()
125-
.success(true)
126122
.message("Found " + genres.size() + " distinct genres")
127123
.data(genres)
128-
.timestamp(Instant.now().toString())
129124
.build();
130125

131126
return ResponseEntity.ok(response);
@@ -142,10 +137,8 @@ public ResponseEntity<SuccessResponse<Movie>> getMovieById(
142137
Movie movie = movieService.getMovieById(id);
143138

144139
SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
145-
.success(true)
146140
.message("Movie retrieved successfully")
147141
.data(movie)
148-
.timestamp(Instant.now().toString())
149142
.build();
150143

151144
return ResponseEntity.ok(response);
@@ -162,10 +155,8 @@ public ResponseEntity<SuccessResponse<Movie>> createMovie(
162155
Movie movie = movieService.createMovie(request);
163156

164157
SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
165-
.success(true)
166158
.message("Movie '" + request.title() + "' created successfully")
167159
.data(movie)
168-
.timestamp(Instant.now().toString())
169160
.build();
170161

171162
return ResponseEntity.status(HttpStatus.CREATED).body(response);
@@ -182,10 +173,8 @@ public ResponseEntity<SuccessResponse<BatchInsertResponse>> createMoviesBatch(
182173
BatchInsertResponse result = movieService.createMoviesBatch(requests);
183174

184175
SuccessResponse<BatchInsertResponse> response = SuccessResponse.<BatchInsertResponse>builder()
185-
.success(true)
186176
.message("Successfully created " + result.insertedCount() + " movies")
187177
.data(result)
188-
.timestamp(Instant.now().toString())
189178
.build();
190179

191180
return ResponseEntity.status(HttpStatus.CREATED).body(response);
@@ -210,10 +199,8 @@ public ResponseEntity<SuccessResponse<Movie>> updateMovie(
210199
Movie movie = movieService.updateMovie(id, request);
211200

212201
SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
213-
.success(true)
214202
.message("Movie updated successfully")
215203
.data(movie)
216-
.timestamp(Instant.now().toString())
217204
.build();
218205

219206
return ResponseEntity.ok(response);
@@ -235,11 +222,9 @@ public ResponseEntity<SuccessResponse<BatchUpdateResponse>> updateMoviesBatch(
235222
BatchUpdateResponse result = movieService.updateMoviesBatch(filter, update);
236223

237224
SuccessResponse<BatchUpdateResponse> response = SuccessResponse.<BatchUpdateResponse>builder()
238-
.success(true)
239225
.message("Update operation completed. Matched " + result.matchedCount() +
240226
" documents, modified " + result.modifiedCount() + " documents.")
241227
.data(result)
242-
.timestamp(Instant.now().toString())
243228
.build();
244229

245230
return ResponseEntity.ok(response);
@@ -257,10 +242,8 @@ public ResponseEntity<SuccessResponse<Movie>> findAndDeleteMovie(
257242
Movie movie = movieService.findAndDeleteMovie(id);
258243

259244
SuccessResponse<Movie> response = SuccessResponse.<Movie>builder()
260-
.success(true)
261245
.message("Movie found and deleted successfully")
262246
.data(movie)
263-
.timestamp(Instant.now().toString())
264247
.build();
265248

266249
return ResponseEntity.ok(response);
@@ -277,10 +260,8 @@ public ResponseEntity<SuccessResponse<DeleteResponse>> deleteMovie(
277260
DeleteResponse result = movieService.deleteMovie(id);
278261

279262
SuccessResponse<DeleteResponse> response = SuccessResponse.<DeleteResponse>builder()
280-
.success(true)
281263
.message("Movie deleted successfully")
282264
.data(result)
283-
.timestamp(Instant.now().toString())
284265
.build();
285266

286267
return ResponseEntity.ok(response);
@@ -301,10 +282,8 @@ public ResponseEntity<SuccessResponse<DeleteResponse>> deleteMoviesBatch(
301282
DeleteResponse result = movieService.deleteMoviesBatch(filter);
302283

303284
SuccessResponse<DeleteResponse> response = SuccessResponse.<DeleteResponse>builder()
304-
.success(true)
305285
.message("Delete operation completed. Removed " + result.deletedCount() + " documents.")
306286
.data(result)
307-
.timestamp(Instant.now().toString())
308287
.build();
309288

310289
return ResponseEntity.ok(response);
@@ -338,10 +317,8 @@ public ResponseEntity<SuccessResponse<List<MovieWithCommentsResult>>> getMoviesW
338317

339318
SuccessResponse<List<MovieWithCommentsResult>> response =
340319
SuccessResponse.<List<MovieWithCommentsResult>>builder()
341-
.success(true)
342320
.message(message)
343321
.data(results)
344-
.timestamp(Instant.now().toString())
345322
.build();
346323

347324
return ResponseEntity.ok(response);
@@ -359,10 +336,8 @@ public ResponseEntity<SuccessResponse<List<MoviesByYearResult>>> getMoviesByYear
359336

360337
SuccessResponse<List<MoviesByYearResult>> response =
361338
SuccessResponse.<List<MoviesByYearResult>>builder()
362-
.success(true)
363339
.message(String.format("Aggregated statistics for %d years", results.size()))
364340
.data(results)
365-
.timestamp(Instant.now().toString())
366341
.build();
367342

368343
return ResponseEntity.ok(response);
@@ -382,10 +357,8 @@ public ResponseEntity<SuccessResponse<List<DirectorStatisticsResult>>> getDirect
382357

383358
SuccessResponse<List<DirectorStatisticsResult>> response =
384359
SuccessResponse.<List<DirectorStatisticsResult>>builder()
385-
.success(true)
386360
.message(String.format("Found %d directors with most movies", results.size()))
387361
.data(results)
388-
.timestamp(Instant.now().toString())
389362
.build();
390363

391364
return ResponseEntity.ok(response);
@@ -440,10 +413,8 @@ public ResponseEntity<SuccessResponse<SearchMoviesResponse>> searchMovies(
440413
.build();
441414

442415
SuccessResponse<SearchMoviesResponse> response = SuccessResponse.<SearchMoviesResponse>builder()
443-
.success(true)
444416
.message(String.format("Found %d movies matching the search criteria", movies.size()))
445417
.data(searchResponse)
446-
.timestamp(Instant.now().toString())
447418
.build();
448419

449420
return ResponseEntity.ok(response);
@@ -465,10 +436,8 @@ public ResponseEntity<SuccessResponse<List<VectorSearchResult>>> vectorSearchMov
465436
List<VectorSearchResult> results = movieService.vectorSearchMovies(q, limit);
466437

467438
SuccessResponse<List<VectorSearchResult>> response = SuccessResponse.<List<VectorSearchResult>>builder()
468-
.success(true)
469439
.message(String.format("Found %d similar movies for query: '%s'", results.size(), q))
470440
.data(results)
471-
.timestamp(Instant.now().toString())
472441
.build();
473442

474443
return ResponseEntity.ok(response);
@@ -489,10 +458,8 @@ public ResponseEntity<SuccessResponse<List<Movie>>> findSimilarMovies(
489458
List<Movie> movies = movieService.findSimilarMovies(movieId, limit);
490459

491460
SuccessResponse<List<Movie>> response = SuccessResponse.<List<Movie>>builder()
492-
.success(true)
493461
.message(String.format("Found %d similar movies", movies.size()))
494462
.data(movies)
495-
.timestamp(Instant.now().toString())
496463
.build();
497464

498465
return ResponseEntity.ok(response);

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/exception/GlobalExceptionHandler.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public ResponseEntity<ErrorResponse> handleResourceNotFoundException(
2929
logger.error("Resource not found: {}", ex.getMessage());
3030

3131
ErrorResponse errorResponse = ErrorResponse.builder()
32-
.success(false)
3332
.message(ex.getMessage())
3433
.error(ErrorResponse.ErrorDetails.builder()
3534
.message(ex.getMessage())
@@ -47,7 +46,6 @@ public ResponseEntity<ErrorResponse> handleValidationException(
4746
logger.error("Validation error: {}", ex.getMessage());
4847

4948
ErrorResponse errorResponse = ErrorResponse.builder()
50-
.success(false)
5149
.message("Validation failed")
5250
.error(ErrorResponse.ErrorDetails.builder()
5351
.message(ex.getMessage())
@@ -67,7 +65,6 @@ public ResponseEntity<ErrorResponse> handleMissingServletRequestParameter(
6765
String message = String.format("Required parameter '%s' is missing", ex.getParameterName());
6866

6967
ErrorResponse errorResponse = ErrorResponse.builder()
70-
.success(false)
7168
.message(message)
7269
.error(ErrorResponse.ErrorDetails.builder()
7370
.message(message)
@@ -85,7 +82,6 @@ public ResponseEntity<ErrorResponse> handleServiceUnavailableException(
8582
logger.error("Service unavailable: {}", ex.getMessage());
8683

8784
ErrorResponse errorResponse = ErrorResponse.builder()
88-
.success(false)
8985
.message(ex.getMessage())
9086
.error(ErrorResponse.ErrorDetails.builder()
9187
.message(ex.getMessage())
@@ -103,7 +99,6 @@ public ResponseEntity<ErrorResponse> handleVoyageAuthException(
10399
logger.error("Voyage AI authentication error: {}", ex.getMessage());
104100

105101
ErrorResponse errorResponse = ErrorResponse.builder()
106-
.success(false)
107102
.message(ex.getMessage())
108103
.error(ErrorResponse.ErrorDetails.builder()
109104
.message(ex.getMessage())
@@ -122,7 +117,6 @@ public ResponseEntity<ErrorResponse> handleVoyageAPIException(
122117
logger.error("Voyage AI API error: {}", ex.getMessage());
123118

124119
ErrorResponse errorResponse = ErrorResponse.builder()
125-
.success(false)
126120
.message("Vector search service unavailable")
127121
.error(ErrorResponse.ErrorDetails.builder()
128122
.message(ex.getMessage())
@@ -140,7 +134,6 @@ public ResponseEntity<ErrorResponse> handleDatabaseOperationException(
140134
logger.error("Database operation error: {}", ex.getMessage());
141135

142136
ErrorResponse errorResponse = ErrorResponse.builder()
143-
.success(false)
144137
.message("Database operation failed")
145138
.error(ErrorResponse.ErrorDetails.builder()
146139
.message(ex.getMessage())
@@ -168,7 +161,6 @@ public ResponseEntity<ErrorResponse> handleMongoWriteException(
168161
}
169162

170163
ErrorResponse errorResponse = ErrorResponse.builder()
171-
.success(false)
172164
.message(message)
173165
.error(ErrorResponse.ErrorDetails.builder()
174166
.message(message)
@@ -187,7 +179,6 @@ public ResponseEntity<ErrorResponse> handleGenericException(
187179
logger.error("Unexpected error occurred", ex);
188180

189181
ErrorResponse errorResponse = ErrorResponse.builder()
190-
.success(false)
191182
.message(ex.getMessage() != null ? ex.getMessage() : "Internal server error")
192183
.error(ErrorResponse.ErrorDetails.builder()
193184
.message(ex.getMessage() != null ? ex.getMessage() : "Internal server error")

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/model/Movie.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import com.fasterxml.jackson.annotation.JsonProperty;
44
import java.util.Date;
55
import java.util.List;
6-
import lombok.*;
6+
import lombok.Builder;
7+
import lombok.EqualsAndHashCode;
8+
import lombok.Getter;
9+
import lombok.Setter;
710
import org.bson.types.ObjectId;
811
import org.springframework.data.annotation.Id;
912
import org.springframework.data.mongodb.core.mapping.Document;

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/model/dto/DirectorStatisticsResult.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.fasterxml.jackson.annotation.JsonInclude;
44
import lombok.Builder;
5+
import lombok.With;
56

67
/**
78
* DTO for director statistics aggregation result.
@@ -25,5 +26,6 @@ public record DirectorStatisticsResult (
2526
/**
2627
* Average IMDB rating of this director's movies.
2728
*/
29+
@With
2830
Double averageRating) {}
2931

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/model/response/ErrorResponse.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ public record ErrorResponse (
4444
*/
4545
String timestamp) implements ApiResponse {
4646

47-
public ErrorResponse {
48-
success = false;
49-
timestamp = Instant.now().toString();
47+
// Partial builder declaration to provide defaults for records (like @Builder.Default for classes)
48+
public static class ErrorResponseBuilder {
49+
private boolean success = false;
50+
private String timestamp = Instant.now().toString();
5051
}
5152

5253
@Override

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/model/response/SuccessResponse.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,10 @@ public record SuccessResponse<T> (
4747
*/
4848
Pagination pagination) implements ApiResponse {
4949

50-
public SuccessResponse {
51-
success = true;
52-
timestamp = Instant.now().toString();
50+
// Partial builder declaration to provide defaults for records (like @Builder.Default for classes)
51+
public static class SuccessResponseBuilder<T> {
52+
private boolean success = true;
53+
private String timestamp = Instant.now().toString();
5354
}
5455

5556
@Override

mflix/server/java-spring/src/main/java/com/mongodb/samplemflix/service/MovieServiceImpl.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,11 +548,7 @@ public List<DirectorStatisticsResult> getDirectorsWithMostMovies(Integer limit)
548548
return results.getMappedResults().stream()
549549
.map(result -> {
550550
if (result.averageRating() != null) {
551-
return new DirectorStatisticsResult(
552-
result.director(),
553-
result.movieCount(),
554-
Math.round(result.averageRating() * 100.0) / 100.0
555-
);
551+
return result.withAverageRating(Math.round(result.averageRating() * 100.0) / 100.0);
556552
}
557553
return result;
558554
})

0 commit comments

Comments
 (0)