[英]Pass @Transactional method result from Service to Controller Layer Spring Boot
I'm trying to lazily fetch a ManyToMany relationship (Courses - Students) from the Service and pass the result to the Controller. While i'm in the Service, no LazyInitializationException
is thrown, thanks to the @Transactional
annotation.我试图从服务中懒惰地获取 ManyToMany 关系(课程 - 学生)并将结果传递给 Controller。当我在服务中时,没有抛出
LazyInitializationException
,这要归功于@Transactional
注释。 However, while i'm in the Controller the LazyInitializationException
is thrown (while getting Course.students
), because the Session was closed.但是,当我在 Controller 时,会抛出
LazyInitializationException
(在获取Course.students
),因为 Session 已关闭。 How can i resolve this issue, without eagerly fetch the Collection?如果不急切地获取集合,我该如何解决这个问题?
That's my code:那是我的代码:
Couse Model辅导员 Model
@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<>();
}
Student Model学生 Model
@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<>();
}
}
Course Repository课程资料库
@Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
}
Course Service课程服务
@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());
}
}
Course Controller课程 Controller
@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应用程序.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
Thanks in advance.提前致谢。
So there are 2 approaches:所以有两种方法:
This is bad for performance and must be avoided at all costs.这对性能不利,必须不惜一切代价避免。
All in all, do not use transactional to keep the db session open to fetch lazy collections. Just join fetch lazy collections in db / dao layer to have the data needed for each endpoint available.总而言之,不要使用事务来保持 db session 打开以获取惰性 collections。只需在 db/dao 层中加入 fetch lazy collections 即可获得每个端点所需的数据。
If you want have a look here for how to use join fetch How to fetch FetchType.LAZY associations with JPA and Hibernate in a Spring Controller如果你想看看这里如何使用 join fetch How to fetch FetchType.LAZY associations with JPA and Hibernate in a Spring Controller
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.