首页 > 解决方案 > 使用 JPA 和 Hibernate 覆盖 CrudeRepository save() 错误

问题描述

我正在尝试使用 Hibernate 和 JpaRepository 覆盖保存功能,但是每次我尝试运行程序时都会出错

错误:(15, 23) java: com.studapp.students.StudentJpaRepository 中的 save(com.studapp.students.Student) 与 org.springframework.data.repository.CrudRepository 中的 save(S) 返回类型 java.util.Optional与 S 不兼容

学生班级:

@Entity
@Table(name = "Student")
public class Student implements Serializable {

    @Id
    @Column(name = "STUDENT_ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long ID;

    @Column(name = "firstName")
    private String firstName;

    @Column(name = "lasttName")
    private String lastName;

    @Column(name = "dateOfBirth")
    private LocalDate dateOfBirth;

    @Column(name = "JMBAG")
    private String JMBAG;

    @Column(name = "numberOfECTS")
    private Integer numberOfECTS;

    @ManyToMany(targetEntity = Course.class )
    @JoinTable(
            name = "student_course" ,
            joinColumns = { @JoinColumn(name = "STUDENT_ID") } ,
            inverseJoinColumns = { @JoinColumn(name = "COURSE_ID") }
    )
    private List<Course> courses;

    public Student(){};

    public Student(String firstName, String lastName, LocalDate dateOfBirth, String jmbag, Integer numberOfECTS) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
        this.JMBAG = jmbag;
        this.numberOfECTS = numberOfECTS;
    }
//getters and setters

控制器类 StudentController :

@RestController
@RequestMapping("student")
@CrossOrigin(origins = "http://localhost:4200")
public class StudentController {
private final StudentService studentService;

public StudentController(StudentService studentService){
    this.studentService = studentService;
}
@PostMapping
public ResponseEntity<StudentDTO> save(@Valid @RequestBody final StudentCommand command){
    return studentService.save(command)
            .map(
                    studentDTO -> ResponseEntity
                            .status(HttpStatus.CREATED)
                            .body(studentDTO)
            )
            .orElseGet(
                    () -> ResponseEntity
                            .status(HttpStatus.CONFLICT)
                            .build()
            );
}

服务 StudentService 的接口:

public interface StudentService {
  Optional<StudentDTO> save(StudentCommand command);
}

服务类 StudentServiceImpl 的实现

@Service
public class StudentServiceImpl implements StudentService{

    private static final int YEARS_AFTER_WHICH_TUITION_SHOULD_BE_PAYED = 30;

    private final StudentJpaRepository studentJpaRepository;

    public StudentServiceImpl(StudentJpaRepository studentJpaRepository){
        this.studentJpaRepository = studentJpaRepository;
    }

    @Override
    public Optional<StudentDTO> save(final StudentCommand command) {
        return studentJpaRepository.save(mapCommmandToStudent(command)).map(this::mapStudentToDTO);
    }

    private StudentDTO mapStudentToDTO(final Student student){
        return new StudentDTO (student.getFirstName(), student.getLastName(), 
    student.getJMBAG(),student.getNumberOfECTS(), shouldTuitionBePayed(student.getDateOfBirth()));
    }

    private Student mapCommmandToStudent(final StudentCommand studentCommand) {
        return new Student(studentCommand.getFirstName(), studentCommand.getLastName(), 
    studentCommand.getDateOfBirth(), studentCommand.getJmbag(), studentCommand.getNumberOfECTS());
    }
}

JpaRepository 的接口:

@Repository
public interface StudentJpaRepository extends JpaRepository<Student, Long> {
    Optional<Student> save(Student student);
}

我在内存数据库中使用 h2:schema.sql

CREATE TABLE IF NOT EXISTS Student (
    STUDENT_ID identity,
    JMBAG CHAR(10) NOT NULL ,
    firstName VARCHAR(50) NOT NULL,
    lastName VARCHAR(50) NOT NULL,
    dateOfBirth DATE NOT NULL,
    numberOfECTS INT NOT NULL
) ;
INSERT INTO Student ( firstName, lastName, dateOfBirth, JMBAG, numberOfECTS)
VALUES ('Jhon' , 'Jhonson' , '1993-05-08' , '0024789510' , 121  );

标签: javaspringhibernatespring-data-jpa

解决方案


为了覆盖现有方法,您必须创建与 CrudRepository 中完全相同的保存方法

您可以执行以下操作:

@Repository
public interface StudentJpaRepository extends JpaRepository<Student, Long> {
    <S extends MyEntity> S save(S entity);
}

MyCustomRepositoryImpl .java

public class MyCustomRepositoryImpl implements StudentJpaRepository {

    @Override
    public <S extends MyBean> S save(S entity) {
       /**
         your custom implementation comes here ...
       */
    }

}


推荐阅读