将 @Transactional 方法结果从 Service 传递到 Controller Layer Spring Boot
Pass @Transactional method result from Service to Controller Layer Spring Boot
我正在尝试从服务中懒惰地获取多对多关系(课程 - 学生)并将结果传递给控制器。当我在服务中时,没有 LazyInitializationException
被抛出,这要归功于 @Transactional
注释。但是,当我在控制器中时,抛出 LazyInitializationException
(同时获得 Course.students
),因为会话已关闭。如果不急切地获取集合,我该如何解决这个问题?
那是我的代码:
Couse 模型
@Entity
@Getter
@Setter
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany
@JoinTable(name = "COURSES_STUDENTS",
joinColumns = {@JoinColumn(name = "COURSE_ID")},
inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID")})
private Set<Student> students;
public Course() {
this.students = new HashSet<>();
}
学生模型
@Entity
@Getter
@Setter
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany(mappedBy = "students")
private Set<Course> courses;
public Student() {
this.courses = new HashSet<>();
}
}
课程资料库
@Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
}
课程服务
@Service
public class CourseService {
private final CourseRepository courseRepository;
@Autowired
public CourseService(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
@Transactional
public ResponseEntity<List<Course>> findAll() {
return this.courseRepository.findAll().isEmpty() ? ResponseEntity.noContent().build()
: ResponseEntity.ok(this.courseRepository.findAll());
}
}
课程管理员
@Controller
@RequestMapping("/")
public class CourseController {
private final CourseService courseService;
@Autowired
public CourseController(CourseService courseService) {
this.courseService = courseService;
}
@GetMapping
public ResponseEntity<List<Course>> index() {
return this.courseService.findAll();
}
}
application.properties
spring.datasource.url=jdbc:h2:~/database;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.jpa.open-in-view=false
spring.mvc.hiddenmethod.filter.enabled=true
logging.level.org.springframework.web=DEBUG
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
提前致谢。
所以有两种方法:
这对性能不利,必须不惜一切代价避免。
- 使用 jpql 查询加入 DAO 层所需的获取惰性集合,以便在需要时在控制器中可用。
总而言之,不要使用事务来保持数据库会话打开以获取惰性集合。只需在 db / dao 层加入 fetch 惰性集合,即可获得每个端点所需的数据。
如果您想在这里查看如何使用 join fetch How to fetch FetchType.LAZY associations with JPA and Hibernate in a Spring Controller
我正在尝试从服务中懒惰地获取多对多关系(课程 - 学生)并将结果传递给控制器。当我在服务中时,没有 LazyInitializationException
被抛出,这要归功于 @Transactional
注释。但是,当我在控制器中时,抛出 LazyInitializationException
(同时获得 Course.students
),因为会话已关闭。如果不急切地获取集合,我该如何解决这个问题?
那是我的代码:
Couse 模型
@Entity
@Getter
@Setter
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany
@JoinTable(name = "COURSES_STUDENTS",
joinColumns = {@JoinColumn(name = "COURSE_ID")},
inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID")})
private Set<Student> students;
public Course() {
this.students = new HashSet<>();
}
学生模型
@Entity
@Getter
@Setter
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany(mappedBy = "students")
private Set<Course> courses;
public Student() {
this.courses = new HashSet<>();
}
}
课程资料库
@Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
}
课程服务
@Service
public class CourseService {
private final CourseRepository courseRepository;
@Autowired
public CourseService(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
@Transactional
public ResponseEntity<List<Course>> findAll() {
return this.courseRepository.findAll().isEmpty() ? ResponseEntity.noContent().build()
: ResponseEntity.ok(this.courseRepository.findAll());
}
}
课程管理员
@Controller
@RequestMapping("/")
public class CourseController {
private final CourseService courseService;
@Autowired
public CourseController(CourseService courseService) {
this.courseService = courseService;
}
@GetMapping
public ResponseEntity<List<Course>> index() {
return this.courseService.findAll();
}
}
application.properties
spring.datasource.url=jdbc:h2:~/database;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.jpa.open-in-view=false
spring.mvc.hiddenmethod.filter.enabled=true
logging.level.org.springframework.web=DEBUG
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
提前致谢。
所以有两种方法:
这对性能不利,必须不惜一切代价避免。
- 使用 jpql 查询加入 DAO 层所需的获取惰性集合,以便在需要时在控制器中可用。
总而言之,不要使用事务来保持数据库会话打开以获取惰性集合。只需在 db / dao 层加入 fetch 惰性集合,即可获得每个端点所需的数据。
如果您想在这里查看如何使用 join fetch How to fetch FetchType.LAZY associations with JPA and Hibernate in a Spring Controller