-1

共有三个类(课程、课程、用户)。

@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "usr")
@Data
public class User extends RepresentationModel<User> implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstname;
    private String lastname;
    private String username;
    private String password;
    @ElementCollection(targetClass = ERole.class, fetch = FetchType.EAGER)
    @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
    @Enumerated(EnumType.STRING)
    private Set<ERole> roles;
}
@Data
@Entity
@NoArgsConstructor
public class Lesson extends RepresentationModel<Lesson> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String startTime;
    private String endTime;
    private String dayOfWeek;
    @ManyToOne
    private User teacher;
}
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
public class Course extends RepresentationModel<Course> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Date startDate;
    private Date endDate;
    private String name;
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<User> teachers;
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<User> students;
    private String description;
    @ManyToMany(cascade = CascadeType.ALL)
    private Set<Lesson> lessons;
}

还有 RestController ( CoursesController)。在 /courses 访问服务器时,我得到所有字段的正确服务器响应

在此处输入图像描述.

@RestController
@RequestMapping("/courses")
public class CoursesController {
    private final CourseService courseService;
    private final UserService userService;
    private final LessonService lessonService;

    @Autowired
    public CoursesController(CourseService courseService, UserService userService, LessonService lessonService) {
        this.courseService = courseService;
        this.userService = userService;
        this.lessonService = lessonService;
    }

    @GetMapping
    @Operation(
          summary = "getAllCourses",
            description = "Returns all available courses"
    )
    public ResponseEntity<Page<Course>> getAllCourses(@PageableDefault(sort = "id", size = 5) Pageable pageable) {
        try {
            Page<Course> coursePage = courseService.findAll(pageable);
            for (Course course : coursePage.getContent())
                course.add(linkTo(methodOn(CoursesController.class).getCourse(course.getId().toString())).withSelfRel());
            return ResponseEntity.ok(courseService.findAll(pageable));
        }
        catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }
    @GetMapping("/{course-id}")
    @Operation(
            summary = "getCourse",
            description = "Returns course by ID"
    )
    public ResponseEntity<Course> getCourse(@PathVariable ("course-id") String courseId) {
        try {
            Course course = courseService.getCourseById(courseId);
            course.add(linkTo(methodOn(CoursesController.class).getCourse(courseId)).withSelfRel());
            return ResponseEntity.ok(course);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}

为什么在通过 ID (GET /courses/{id}) 请求课程时,Spring 会返回一个不完整的对象(尽管我手动添加了多个教师、学生和课程)?

在此处输入图像描述

我需要获取对象的所有字段。我的 CourseRepository 下面。

@Repository
@Transactional
public interface CourseRepository extends JpaRepository<Course, Long> {
}

我的 CourseService 下面。

@Service
public class CourseService {
    private final CourseRepository courseRepository;
    private final LessonRepository lessonRepository;
    private final UserRepository userRepository;

    @Autowired
    public CourseService(CourseRepository courseRepository, LessonRepository lessonRepository, UserRepository userRepository) {
        this.courseRepository = courseRepository;
        this.lessonRepository = lessonRepository;
        this.userRepository = userRepository;
    }

    public Page<Course> findAll(Pageable pageable) {
        return courseRepository.findAll(pageable);
    }

    public Course createCourse(CourseDto courseDto) {
        Course course = new Course(courseDto.getStartDate(), courseDto.getEndDate(), courseDto.getName(), courseDto.getDescription());
        return courseRepository.saveAndFlush(course);
    }

    public Optional<Course> getCourseById(String id) {
        return courseRepository.findById(Long.parseLong(id));
    }

    public Course updateCourse(CourseDto courseDto, String id) {
        Course course = courseRepository.findById(Long.parseLong(id)).get();
        course.setStartDate(courseDto.getStartDate());
        course.setEndDate(courseDto.getEndDate());
        course.setName(courseDto.getName());
        course.setDescription(courseDto.getDescription());
        return courseRepository.saveAndFlush(course);
    }

    public Page<Lesson> getLessonsByCourse(String courseId, Pageable pageable) {
        Course course = courseRepository.findById(Long.parseLong(courseId)).get();
        return new PageImpl<>(new ArrayList<>(course.getLessons()), pageable, course.getLessons().size());
    }

    public Course addLesson(String courseId, LessonDto lessonDto) {
        Course course = courseRepository.findById(Long.parseLong(courseId)).get();
        Lesson lesson = new Lesson();
        lesson.setStartTime(lessonDto.getStartTime());
        lesson.setEndTime(lessonDto.getFinishTime());
        lesson.setDayOfWeek(lessonDto.getDayOfWeek());
        lesson.setTeacher(userRepository.getUserById(lessonDto.getTeacherId()));
        lessonRepository.saveAndFlush(lesson);
        System.out.println(lesson);
        course.getLessons().add(lesson);
        return courseRepository.saveAndFlush(course);
    }

    public void deleteCourse(String id) {
        courseRepository.deleteById(Long.parseLong(id));
    }
}
4

1 回答 1

0

我也会(或可能)期待的。我会为那些额外的关系生成链接(至少通常使用 Spring Data REST 处理会发生这种情况)。我想知道如果您从 JPA 模型中抛弃 RepresentationModel 并然后公开 Course 会发生什么。如前所述,您真的不希望您的 JPA 和 HATEOAS 东西交织在一起。您想要有一个专门的投影/dto 来公开。为什么它对您的 findAll 有效。好吧,您没有添加指向它的链接(尽管您认为确实如此,但您的 findAll 执行了两次!)。

从 User 类中删除了 RepresentationModel。感谢@M.Deinum

于 2022-02-01T10:48:38.233 回答