I’m trying to store images in MySQL using Spring boot, I have a user entity and I want to create a Many To One relationship between my FileUpload entity.
I’m using react on the front end and the purpose of this upload service is to have profile pictures that a user can set themselves but I’d first like to get the relationship between the User and FileUpload entities correct.
The issue I have is that the joinColumn in the FileUpload table does not save the User Entities id when a user uploads an image. It just returns a null value in the foreign key field.
FileUpload.java
@Entity @Table(name="file_upload") public class FileUpload { @Id @GenericGenerator(name = "uuid", strategy = "uuid2") @GeneratedValue(generator = "uuid") private String id; private String name; private String type; @Lob private byte[] data; @ManyToOne @JoinColumn( name="user_id") private User user; public FileUpload() { } public FileUpload(String name, String type, byte[] data) { this.name = name; this.type = type; this.data = data; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } public byte[] getData() { return data; } public void setData(byte[] data) { this.data = data; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
FileUploadService.java
- I also have a repository for this, with no custom methods inside.
@Service public class FileUploadService { @Autowired private FileUploadRepository fileUploadRepository; public FileUpload store(MultipartFile file) throws IOException { String fileName = StringUtils.cleanPath(file.getOriginalFilename()); FileUpload fileDB = new FileUpload(fileName, file.getContentType(), file.getBytes()); return fileUploadRepository.save(fileDB); } public FileUpload getFile(String id) { return fileUploadRepository.findById(id).get(); } public Stream<FileUpload> getAllFiles() { return fileUploadRepository.findAll().stream(); } }
FileUploadController.java
@Controller @CrossOrigin() public class FileUploadController { @Autowired private FileUploadService fileUploadService; @PostMapping("/upload") public ResponseEntity<?> uploadFile(@RequestParam("file")MultipartFile file) { String message = ""; try { fileUploadService.store(file); message = "Uploaded the file successfully: " + file.getOriginalFilename(); return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse(true, message)); } catch (Exception e) { message = "Could not upload the file: " + file.getOriginalFilename() + "!"; return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ApiResponse(true, message)); } } @GetMapping("/files") public ResponseEntity<List<?>> getListFiles() { List<FileUploadResponse> files = fileUploadService.getAllFiles().map(dbFile -> { String fileDownloadUri = ServletUriComponentsBuilder .fromCurrentContextPath() .path("/files/") .path(dbFile.getId()) .toUriString(); return new FileUploadResponse( dbFile.getName(), fileDownloadUri, dbFile.getType(), dbFile.getData().length); }).collect(Collectors.toList()); return ResponseEntity.status(HttpStatus.OK).body(files); } @GetMapping("/files/{id}") public ResponseEntity<byte[]> getFile(@PathVariable String id) { FileUpload fileUpload = fileUploadService.getFile(id); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + fileUpload.getName() + """) .body(fileUpload.getData()); } }
I have the same relationship with a confirmation token entity i have to confirm a users email which does work properly with the ManyToOne relationship but this doesn’t. I am using the same relationship mapping but it gives me null values as seen above.
@ManyToOne @JoinColumn( name="user_id") private User user;
I can upload the file fine but I want to be able to keep track of a user and their files.
Advertisement
Answer
You need to assign a user to this entity:
FileUpload fileDB = new FileUpload(fileName, file.getContentType(), file.getBytes()); fileDB.setUser(userThatSentImage); // you need to set user return fileUploadRepository.save(fileDB);
How do you authenticate users? If you are using spring security, here you can find how to retrieve user from session: https://www.baeldung.com/get-user-in-spring-security