将 @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

提前致谢。

所以有两种方法:

这对性能不利,必须不惜一切代价避免。

  1. 使用 jpql 查询加入 DAO 层所需的获取惰性集合,以便在需要时在控制器中可用。

总而言之,不要使用事务来保持数据库会话打开以获取惰性集合。只需在 db / dao 层加入 fetch 惰性集合,即可获得每个端点所需的数据。

如果您想在这里查看如何使用 join fetch How to fetch FetchType.LAZY associations with JPA and Hibernate in a Spring Controller