Spring Boot 2.7.x JPA @ManyToOne join returns empty list on GET, but works on POST
03:45 17 Nov 2025

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?

java mysql spring-boot hibernate spring-data-jpa