In a Spring Boot 2.7.x application with Hibernate/JPA, there are two tables:
tickets
complaint_id (PK, VARCHAR(255))
attachment
complaint_id (FK, VARCHAR(255))
other fields: id, file_name, file_type, data
The schema looks correct: both columns are VARCHAR(255), and the foreign key fk_attachment_complaint exists.
SELECT a.id, a.file_name, a.complaint_id, t.complaint_id
FROM attachment a
JOIN tickets t ON a.complaint_id = t.complaint_id
WHERE t.complaint_id = 'IND-2025-0001';
This returns rows as expected.
Entities:
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name = "TICKETS")
public class Tickets {
@Id
@GeneratedValue(generator = "complaint-id-generator")
@GenericGenerator(name = "complaint-id-generator", strategy = "com.example.ticket.utils.ComplaintIdGenerator")
@Column(name = "complaint_id")
private String complaintId;
// other fields...
}
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Table(name = "ATTACHMENT")
public class Attachment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String fileName;
private String fileType;
private byte[] data;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "complaint_id", referencedColumnName = "complaint_id", nullable = false)
private Tickets ticket;
}
Repository:
@Query("SELECT a FROM Attachment a WHERE a.ticket.complaintId = :complaintId")
List findByComplaintId(@Param("complaintId") String complaintId);
Controller methods:
@PostMapping("/attachments/{complaintId}")
public ResponseEntity> handleAttachment(
@PathVariable String complaintId,
@RequestParam(value = "file", required = false) MultipartFile file) {
if (file == null || file.isEmpty()) {
// No file uploaded — just return all attachments
List attachments = attachmentService.getAttachmentsByComplaintId(complaintId);
return ResponseEntity.ok(attachments);
}
// File uploaded — save it, then return updated list
attachmentService.uploadImage(complaintId, file);
List updatedAttachments = attachmentService.getAttachmentsByComplaintId(complaintId);
return ResponseEntity.ok(updatedAttachments);
}
@GetMapping("/attachments/{complaintId}")
public ResponseEntity> getAttachments(@PathVariable String complaintId) {
List attachments = attachmentService.getAttachmentsByComplaintId(complaintId);
return ResponseEntity.ok(attachments);
}
Problem: When I call this repository method from a GET endpoint, Hibernate generates the correct SQL:
select a.id, a.file_name, a.file_type, a.complaint_id
from attachment a
left outer join tickets t on a.complaint_id = t.complaint_id
where t.complaint_id = ?
...but the result is always [] (empty list). Even though the DB has matching rows and the manual SQL join returns data.
Strangely, When the same repository method is invoked within a POST endpoint (after uploading a file), it executes successfully and returns the full list of attachments.
Question:
Why does the repository method return an empty list on GET, but works correctly on POST in Spring Boot 2.7.x?
What aspect of transaction handling, session management, entity mapping, or JPA behavior might explain the difference between endpoints?