| 61 | | PetOwner owner = petOwnerRepository.findById(ownerId).orElseThrow(() -> new IllegalArgumentException("Invalid owner")); |
| 62 | | PetSitter sitter = petSitterRepository.findById(sitterId).orElseThrow(() -> new IllegalArgumentException("Invalid sitter")); |
| | 73 | logger.info("Attempting to create booking. Owner: {}, Sitter: {}", ownerId, sitterId); |
| | 74 | |
| | 75 | // 1. Initial Validation |
| | 76 | if (dateFrom == null || dateTo == null || dateFrom.isAfter(dateTo)) { |
| | 77 | logger.error("VALIDATION FAILED: Invalid date range provided"); |
| | 78 | throw new IllegalArgumentException("Booking dates are invalid"); |
| | 79 | } |
| | 80 | if (petIds == null || petIds.isEmpty()) { |
| | 81 | logger.error("VALIDATION FAILED: No pets selected for booking"); |
| | 82 | throw new IllegalArgumentException("At least one pet must be selected"); |
| | 83 | } |
| | 84 | |
| | 85 | // 2.Fetch Entities |
| | 86 | PetOwner owner = petOwnerRepository.findById(ownerId).orElseThrow(() -> { |
| | 87 | logger.error("VALIDATION FAILED: Owner not found with ID: {}", ownerId); |
| | 88 | return new IllegalArgumentException("Invalid owner"); |
| | 89 | }); |
| | 90 | |
| | 91 | PetSitter sitter = petSitterRepository.findById(sitterId).orElseThrow(() -> { |
| | 92 | logger.error("VALIDATION FAILED: Sitter not found with ID: {}", sitterId); |
| | 93 | return new IllegalArgumentException("Invalid sitter"); |
| | 94 | }); |
| | 95 | |
| 103 | | PetOwner owner = petOwnerRepository.findById(ownerId).orElseThrow(() -> new IllegalArgumentException("Invalid owner ID")); |
| 104 | | PetType petType = petTypeRepository.findById(petTypeId).orElseThrow(() -> new IllegalArgumentException("Invalid pet type ID")); |
| | 145 | logger.info("Attempting to add pet '{}' for owner ID: {}", name, ownerId); |
| | 146 | |
| | 147 | if (name == null || name.isBlank()) { |
| | 148 | logger.error("VALIDATION FAILED: Pet name is null or empty"); |
| | 149 | throw new IllegalArgumentException("Pet name is strictly required"); |
| | 150 | } |
| | 151 | |
| | 152 | // 1. Read/Verify Owner exists |
| | 153 | PetOwner owner = petOwnerRepository.findById(ownerId).orElseThrow(() -> { |
| | 154 | logger.error("VALIDATION FAILED: Owner not found with ID: {}", ownerId); |
| | 155 | return new IllegalArgumentException("Invalid owner ID"); |
| | 156 | }); |
| | 157 | |
| | 158 | // 2. Read/Verify PetType exists |
| | 159 | PetType petType = petTypeRepository.findById(petTypeId).orElseThrow(() -> { |
| | 160 | logger.error("VALIDATION FAILED: Pet type not found with ID: {}", petTypeId); |
| | 161 | return new IllegalArgumentException("Invalid pet type ID"); |
| | 162 | }); |
| 124 | | Booking booking = bookingRepository.findById(bookingId).orElseThrow(() -> new IllegalArgumentException("Invalid booking")); |
| | 187 | logger.info("Attempting to add review for booking ID: {}", bookingId); |
| | 188 | |
| | 189 | if (rating == null || rating < 1 || rating > 5) { |
| | 190 | logger.error("VALIDATION FAILED: Invalid rating: {}", rating); |
| | 191 | throw new IllegalArgumentException("Rating must be between 1 and 5"); |
| | 192 | } |
| | 193 | |
| | 194 | Booking booking = bookingRepository.findById(bookingId).orElseThrow(() -> { |
| | 195 | logger.error("VALIDATION FAILED: Booking not found with ID: {}", bookingId); |
| | 196 | return new IllegalArgumentException("Invalid booking"); |
| | 197 | }); |
| | 198 | |
| | 199 | // 1. Validate Business Logic |
| | 200 | if (!"Completed".equalsIgnoreCase(booking.getStatus())) { |
| | 201 | logger.error("VALIDATION FAILED: Cannot review booking in status: {}", booking.getStatus()); |
| | 202 | throw new IllegalStateException("Only completed bookings can be reviewed"); |
| | 203 | } |
| | 204 | |
| | 205 | // 2. Create and save the review |
| | 228 | } |
| | 229 | }}} |
| | 230 | |
| | 231 | === Cascading Deletes & Rollback Demonstration === |
| | 232 | This method deletes a user and all of their related data. If the application crashes before the final step, all previous deletions in the transaction are automatically rolled back, preventing orphaned data. |
| | 233 | {{{ |
| | 234 | #!java |
| | 235 | @Transactional |
| | 236 | public void deleteUserAccount(String userId) { |
| | 237 | logger.info("Attempting to securely delete user account with ID: {}", userId); |
| | 238 | |
| | 239 | // 1. Fetch and delete all bookings associated with the user |
| | 240 | List<Booking> ownerBookings = bookingService.getBookingsForOwner(userId); |
| | 241 | ownerBookings.forEach(b -> bookingService.deleteBooking(b.getBookingId())); |
| | 242 | |
| | 243 | List<Booking> sitterBookings = bookingService.getBookingsForSitter(userId); |
| | 244 | sitterBookings.forEach(b -> bookingService.deleteBooking(b.getBookingId())); |
| | 245 | |
| | 246 | // 2. Delete all pets owned by this user |
| | 247 | List<Pet> pets = petService.getPetsByOwner(userId); |
| | 248 | pets.forEach(p -> petService.deletePetAdmin(p.getPetId())); |
| | 249 | |
| | 250 | // Uncomment this temporarily for testing, validation for deletion |
| | 251 | // if (true) { |
| | 252 | // throw new RuntimeException("Simulated Server Crash!"); |
| | 253 | // } |
| | 254 | |
| | 255 | // 3. Delete the user finally |
| | 256 | userRepository.deleteById(userId); |
| | 257 | logger.info("Successfully deleted user account and all related data for ID: {}", userId); |