Столкнулся со следующей проблемой: при попытке прочитать большой файл из базы данных PostgreSQL в приложении Spring Boot с использованием фреймворка Spring Data JPA все данные загружаются в память, хотя в спецификации класса Blob указано иное:
Код: Выделить всё
By default drivers, implement Blob using an SQL locator (BLOB), which means that a Blob object contains a logical pointer to the SQL BLOB data rather than the data itself.Код: Выделить всё
@RestController
class LargeFileController(
val fileRepo: FileContentRepo
) {
@PostMapping("/file", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
fun saveFile(@RequestBody file: MultipartFile) {
fileRepo.save(LargeFileContent(file))
}
@GetMapping("/file/{id}", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
@Transactional
fun getFileById(@PathVariable("id") id: Long): InputStreamResource {
val file = fileRepo.findById(id).orElseThrow()
// Here I see that all the data is stored in memory (regardless of file size)
// in the InputStream buffer (in the screenshot below)
// If I turn off the database at this point, I still have access to the entire contents of the file.
val content = file.content
return InputStreamResource {
file.content.binaryStream
}
}
}
@Entity
@Table(name = "file_content")
class LargeFileContent (
@Column(nullable = false)
@Lob
@JdbcTypeCode(java.sql.Types.BINARY)
val content: Blob,
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long?=null,
) {
constructor(file: MultipartFile) : this(
content = BlobProxy.generateProxy(file.inputStream, file.size)
)
}
@Repository
interface FileContentRepo: JpaRepository {
}

Моя идея заключалась в том, чтобы сохранить входной поток из базы данных во временный файл на диске, а затем вернуть входной поток из этого файла клиенту (чтобы не задерживать соединение с базой данных, пока клиент читает). Можно ли читать данные из Blob частями, а не загружать все содержимое в память сразу?
Заранее спасибо за ответы!
Подробнее здесь: https://stackoverflow.com/questions/798 ... pring-data
Мобильная версия