簡體   English   中英

將 @Transactional 方法結果從 Service 傳遞到 Controller 層 Spring Boot

[英]Pass @Transactional method result from Service to Controller Layer Spring Boot

我試圖從服務中懶惰地獲取 ManyToMany 關系(課程 - 學生)並將結果傳遞給 Controller。當我在服務中時,沒有拋出LazyInitializationException ,這要歸功於@Transactional注釋。 但是,當我在 Controller 時,會拋出LazyInitializationException (在獲取Course.students ),因為 Session 已關閉。 如果不急切地獲取集合,我該如何解決這個問題?

那是我的代碼:

輔導員 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<>();
    }

學生 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<>();
    }
}

課程資料庫

@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

@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();
    }
}

應用程序.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. Spring Boot 中的這個 spring.jpa.open-in-view=true 屬性是什么?

這對性能不利,必須不惜一切代價避免。

  1. 使用 jpql 查詢加入 DAO 層所需的 fetch lazy collections,以便在需要時可以在 controller 中使用它們。

總而言之,不要使用事務來保持 db session 打開以獲取惰性 collections。只需在 db/dao 層中加入 fetch lazy collections 即可獲得每個端點所需的數據。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM