I have a Spring Boot app (Hibernate + JPA) and I need to fetch all courses objects from PostgreSQL. This objects also contain an image. In the DB, they are store like LOB. @Transactional
only work on ddl-auto:create-drop.
@Transactional
public List<CourseDto> getCourses() {
List<Courses> courses = courseRepositoryDao.findAllByIsCourseFreeAndIsCourseActive(true, true);
List<CourseDto> coursesNameDto = courses
.stream()
.peek(i -> i.setLogo(decompressZLib(i.getLogo())))
.map(course -> modelMapper.map(CourseMapper.toUserDtoFreeCourses(course), CourseDto.class)).collect(Collectors.toList());
System.out.println("**************************" + coursesNameDto + "**********************");
return coursesNameDto;
}
// uncompress the image bytes before returning it to the angular application
public static byte[] decompressZLib(byte[] data) {
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
try {
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
} catch (IOException ioe) {
} catch (DataFormatException e) {
}
return outputStream.toByteArray();
}
CourseMapper:
@Component
public class CourseMapper {
public static CourseDto toUserDtoFreeCourses(Courses course) {
return new CourseDto()
.setCourseId(course.getId())
.setCourseName(course.getCourseName())
.setCourseDescription(course.getCourseDescription())
.setCoursePrice(course.getCoursePrice())
.setIsCourseFree(course.getIsCourseFree())
.setIsCourseActive(course.getIsCourseActive())
.setLogo(course.getLogo());
}
If I don't use @Transactional I cannot take the object from db.
How can I use @Transactional even if ddl-auto is set to update? Why it doesn't work with "update".
When ddl-auto is on update the request from POSTMAN doesn't work.
I doubt that this is related to ddl-auto
. You do not really specify what "doesn't work" means exactly, therefore I can only guess.
The problem might be, that you manipulate your entity in your stream cascade with .peek(i -> i.setLogo(decompressZLib(i.getLogo())))
. This is probably not what you want. You should decompress the image in the mapping step instead, such that the uncompressed data is not written back to the Courses
entity, but rather to CoursesDto
.
Edit: Instead decompressing it directly in the controller, you can also do it in the mapper:
.setLogo(decompressZLib(course.getLogo()))
For that you need to put the decompression method in the mapper as well.