使用 ddl-auto 从 PostgreSQL 获取图像时,@Transactional 不起作用:更新
@Transactional doesn't work when fetching an image from PostreSQL with ddl-auto: update
我有一个 Spring 启动应用程序 (Hibernate + JPA),我需要从 PostgreSQL 获取所有课程对象。此对象还包含图像。在数据库中,它们像 LOB 一样存储。 @Transactional
仅适用于 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();
}
课程映射器:
@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());
}
如果我不使用@Transactional,我就无法从数据库中获取对象。
即使ddl-auto 设置为更新,我如何使用@Transactional?
为什么它不适用于“更新”。
当 ddl-auto 处于更新状态时,来自 POSTMAN 的请求不起作用。
我怀疑这与ddl-auto
有关。您并没有真正说明“不起作用”的确切含义,因此我只能猜测。
问题可能是,您在与 .peek(i -> i.setLogo(decompressZLib(i.getLogo())))
的流级联中操纵您的实体。这可能不是您想要的。您应该改为在映射步骤中解压缩图像,这样未压缩的数据就不会写回 Courses
实体,而是写回 CoursesDto
.
编辑:直接在controller中解压,也可以在mapper中解压:
.setLogo(decompressZLib(course.getLogo()))
为此,您还需要将解压方法也放入映射器中。
我有一个 Spring 启动应用程序 (Hibernate + JPA),我需要从 PostgreSQL 获取所有课程对象。此对象还包含图像。在数据库中,它们像 LOB 一样存储。 @Transactional
仅适用于 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();
}
课程映射器:
@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());
}
如果我不使用@Transactional,我就无法从数据库中获取对象。
即使ddl-auto 设置为更新,我如何使用@Transactional? 为什么它不适用于“更新”。
当 ddl-auto 处于更新状态时,来自 POSTMAN 的请求不起作用。
我怀疑这与ddl-auto
有关。您并没有真正说明“不起作用”的确切含义,因此我只能猜测。
问题可能是,您在与 .peek(i -> i.setLogo(decompressZLib(i.getLogo())))
的流级联中操纵您的实体。这可能不是您想要的。您应该改为在映射步骤中解压缩图像,这样未压缩的数据就不会写回 Courses
实体,而是写回 CoursesDto
.
编辑:直接在controller中解压,也可以在mapper中解压:
.setLogo(decompressZLib(course.getLogo()))
为此,您还需要将解压方法也放入映射器中。