我遇到了这样一个问题,当为医生调用GET(getDoctorByName)方法时,我得到了关于医生的所有信息,除了categories字段(其中有条目,但它返回给我一个空数组)。创建医生记录和类别工作,并为医生添加一个类别。在数据库中创建数据:第一节第一节第一节第一节第一节第二节第一节
我需要改变什么,或者我做错了什么?
医生实体:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "doctor")
public class Doctor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String password;
@Column(name = "first_name")
private String fname;
@Column(name = "last_name")
private String lname;
private String description;
private String number;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(
name = "doctor_category",
joinColumns = @JoinColumn(name = "doctor_id"),
inverseJoinColumns = @JoinColumn(name = "category_id")
)
private Set<Category> categories;
}
类别实体:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "category")
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "categories", fetch = FetchType.LAZY)
private Set<Doctor> doctors;
}
类别和医生库:
@Repository
public interface CategoryRepository extends JpaRepository<Category, Long> {
List<Category> findByName(String name);
}
@Repository
public interface DoctorRepository extends JpaRepository<Doctor, Long> {
@EntityGraph(attributePaths = "categories")
List<Doctor> findByFnameAndLname(String fname, String lname);
@EntityGraph(attributePaths = "categories")
List<Doctor> findByFname(String fname);
@EntityGraph(attributePaths = "categories")
List<Doctor> findByLname(String lname);
}
分类服务:
@Service
public class CategoryService {
@Autowired
private CategoryRepository categoryRepository;
public Category createCategory(Category category) {
return categoryRepository.save(category);
}
public Category editCategory(Long categoryId, Category myCategory) {
Category category = categoryRepository.findById(categoryId)
.orElseThrow(() -> new ResourceNotFoundException("Категория с id: " + categoryId + " не найден"));
category.setName(myCategory.getName());
categoryRepository.save(category);
return category;
}
public List<Category> getCategoryByName(String name) {
List<Category> categories;
if (name != null) {
categories = categoryRepository.findByName(name);
} else categories = categoryRepository.findAll();
return categories;
}
public HttpStatus deleteCategory(Long categoryId) {
categoryRepository.deleteById(categoryId);
return HttpStatus.OK;
}
}
医生服务:
@Service
public class DoctorService {
@Autowired
private DoctorRepository doctorRepository;
@Autowired
private CategoryRepository categoryRepository;
public Doctor createDoctor(Doctor doctor) {
return doctorRepository.save(doctor);
}
public Doctor editDoctor(Long doctorId, Doctor myDoctor) {
Doctor doctor = doctorRepository.findById(doctorId)
.orElseThrow(() -> new ResourceNotFoundException("Доктор с id: " + doctorId + " не найден"));
doctor.setEmail(myDoctor.getEmail());
doctor.setPassword(myDoctor.getPassword());
doctor.setFname(myDoctor.getFname());
doctor.setLname(myDoctor.getLname());
doctor.setDescription(myDoctor.getDescription());
doctor.setNumber(myDoctor.getNumber());
return doctorRepository.save(doctor);
}
public Doctor addCategoryForDoctor(Long doctorId, Long categoryId) {
Doctor doctor = doctorRepository.findById(doctorId)
.orElseThrow(() -> new ResourceNotFoundException("Доктор с id: " + doctorId + " не найден"));
Category category = categoryRepository.findById(categoryId)
.orElseThrow(() -> new ResourceNotFoundException("Категория с id: " + categoryId + " не найден"));
Set<Category> categories = doctor.getCategories();
categories.add(category);
doctor.setCategories(categories);
return doctorRepository.save(doctor);
}
public List<Doctor> getAllDoctors() {
List<Doctor> doctors = doctorRepository.findAll();
for (Doctor doctor : doctors) {
// вызовите getCategories() у каждого доктора, чтобы загрузить связанные категории
doctor.getCategories().size();
}
return doctors;
}
public List<Doctor> getDoctorByName(String fname, String lname) {
List<Doctor> doctors;
if (fname != null && lname != null) {
doctors = doctorRepository.findByFnameAndLname(fname, lname);
} else if (fname != null) {
doctors = doctorRepository.findByFname(fname);
} else if (lname != null) {
doctors = doctorRepository.findByLname(lname);
} else {
doctors = doctorRepository.findAll();
}
return doctors;
}
public HttpStatus deleteDoctor(Long doctorId) {
doctorRepository.deleteById(doctorId);
return HttpStatus.OK;
}
}
医生控制器:
@RestController
@RequestMapping("/doctor")
public class DoctorController {
@Autowired
private DoctorService doctorService;
@PostMapping
public ResponseEntity<Doctor> createDoctor(@RequestBody Doctor doctor) {
return ResponseEntity.ok(doctorService.createDoctor(doctor));
}
@PutMapping
public ResponseEntity<Doctor> editDoctor(@RequestParam Long doctorId, @RequestBody Doctor doctor) {
return ResponseEntity.ok(doctorService.editDoctor(doctorId, doctor));
}
@PutMapping("/add/category")
public ResponseEntity<Doctor> addCategoryForDoctor(@RequestParam Long doctorId, @RequestParam Long categoryId) {
return ResponseEntity.ok(doctorService.addCategoryForDoctor(doctorId, categoryId));
}
@GetMapping("/all")
public ResponseEntity<List<Doctor>> get() {
return ResponseEntity.ok(doctorService.getAllDoctors());
}
@GetMapping
public ResponseEntity<List<Doctor>> getDoctorByName(@RequestParam(required = false) String fname,
@RequestParam(required = false) String lname) {
return ResponseEntity.ok(doctorService.getDoctorByName(fname, lname));
}
@DeleteMapping
public ResponseEntity<HttpStatus> deleteDoctor(@RequestParam Long doctorId) {
return ResponseEntity.ok(doctorService.deleteDoctor(doctorId));
}
}
类别控制器:
@RestController
@RequestMapping("/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
@PostMapping
public ResponseEntity<Category> createCategory(@RequestBody Category category) {
return ResponseEntity.ok(categoryService.createCategory(category));
}
@PutMapping
public ResponseEntity<Category> editCategory(@RequestParam Long categoryId, @RequestBody Category category) {
return ResponseEntity.ok(categoryService.editCategory(categoryId, category));
}
@GetMapping
public ResponseEntity<List<Category>> getCategoryByName(@RequestParam(required = false) String name) {
return ResponseEntity.ok(categoryService.getCategoryByName(name));
}
@DeleteMapping
public ResponseEntity<HttpStatus> deleteCategory(@RequestBody Long categoryId) {
return ResponseEntity.ok(categoryService.deleteCategory(categoryId));
}
}
2条答案
按热度按时间ckocjqey1#
一个解决方案是将Doctor类中的FetchType.LAZY更改为FetchType.EAGER。您可以在此here中找到更多信息。
在“医生实体”中更改此
变成这样
解决此问题的另一种方法是在Category和Doctor类上将@Data注解替换为@Getter和@Setter注解。
此外,通过控制器传递实体并不是一个好的做法。最好使用DTO来代替。您可以阅读有关here的更多信息。
以下是类别和医生的DTO类示例:
DoctorDTO
分类DTO
另外,将DoctorController中的“get”函数更改为使用DTO。我的建议是对所有其他函数也这样做,以便通过DTO而不是实体来完成与外部世界的通信。
最后,修改DoctorService中的getAllDoctors函数如下所示:
g2ieeal72#
在实体Doctor中,你已经为类别集合定义了fetch type lazy。这意味着直到你用代码访问它,集合才从数据库中加载。
解决办法
1.将提取类型更改为渴望或
1.在服务类中为所有医生调用getCategories.size()
1.在存储库中,您可以使用EntityGraph注解,如:
(请注意使用{},因为 attributePaths 是一个数组)