首页 > 解决方案 > 如何在 JPA 和 Spring Boot 中正确构建和实现 HAS-A(组合)和 Hibernate

问题描述

我开始研究我在 Spring Boot 中创建的评分系统项目。我现在正在工作的 2 个 JPA 实体是TeacherSection(教师的咨询课)。但是,我不确定如何通过 JPA 注释正确实现组合(HAS-A关系)以表达“1 位教师有 1 个咨询班”并且不会出错。

我的目标是当我调用教师的 REST API 端点(例如)时,能够在 JSON 响应中包含Section(咨询类)信息Teacherlocalhost:8080/grading/teachers/

Section目前,我在邮递员(类中没有属性)中得到的响应Teacher

localhost:8080/grading/teachers/

[
    {
        "id": 1,
        "employeeId": 20210001,
        "firstName": "John",
        "middleName": "Anyone",
        "lastName": "Doe",
        "dateCreated": "2021-08-29T13:13:29.000+00:00",
        "active": true,
        "adviser": false
    }
]

Section咨询类)尚未包括在内

下面是Teacher, Section, 和REST Controller类定义(我暂时注释Section sectionAdvisory了它的get()andset()方法

抽象实体

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.MappedSuperclass;

import javax.persistence.Id;

@MappedSuperclass 
public class AbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private boolean isActive;
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

老师

import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToOne;

@Entity
public class Teacher extends AbstractEntity{
    
    @Column(name="employee_id")
    private int employeeId;
    
    @Column(name="first_name")
    private String firstName;
    
    @Column(name="middle_name")
    private String middleName;
    
    @Column(name="last_name")
    private String lastName;
    
    @Column(name="is_adviser")
    private boolean isAdviser;
    
    @Column(name="is_active")
    private boolean isActive;
    
    @Column(name="date_created")
    private Timestamp dateCreated;
    
//  @OneToOne
//  Section sectionAdvisory;
    
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getMiddleName() {
        return middleName;
    }
    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public boolean isAdviser() {
        return isAdviser;
    }
    public void setAdviser(boolean isAdviser) {
        this.isAdviser = isAdviser;
    }
        
    public boolean isActive() {
        return isActive;
    }
    public void setActive(boolean isActive) {
        this.isActive = isActive;
    }
    public Timestamp getDateCreated() {
        return dateCreated;
    }
    public void setDateCreated(Timestamp dateCreated) {
        this.dateCreated = dateCreated;
    }
    
//  public Section getSectionAdvisory() {
//      return sectionAdvisory;
//  }
//  public void setSectionAdvisory(Section sectionAdvisory) {
//      this.sectionAdvisory = sectionAdvisory;
//  }
    @Override
    public String toString() {
        return "Teacher [employeeId=" + employeeId + ", firstName=" + firstName + ", middleName=" + middleName
                + ", lastName=" + lastName + ", isAdviser=" + isAdviser + "]";
    }
}

部分

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name="section")
public class Section extends AbstractEntity{
    
    @Column(name = "section_name")
    private String sectionName;
    
    @Column(name = "is_active")
    private boolean isActive;

    public String getSectionName() {
        return sectionName;
    }

    public void setSectionName(String sectionName) {
        this.sectionName = sectionName;
    }

    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean isActive) {
        this.isActive = isActive;
    }
}

TeacherRestController

@RestController
@RequestMapping("/teachers")
@CrossOrigin(origins = "http://localhost:4200")
public class TeacherRestController {

    @Autowired
    TeacherRepository teacherRepository;
    
    
    @GetMapping
    public List<Teacher> getTeachers(){
        //GET localhost:8080/grading/teachers
        return teacherRepository.findAll();
    }
    
    @PostMapping
    public Teacher createTeacher(@RequestBody Teacher teacher) {
        return teacherRepository.save(teacher);
    }
    
    @PutMapping
    public Teacher updateTeacher(@RequestBody Teacher teacher) {
        return teacherRepository.save(teacher);
    }
    
    @DeleteMapping("/{id}")
    public void deleteTeacher(@PathVariable("id") Long id) {
        //DELETE localhost:8080/grading/teachers/idgoeshere
        //example : localhost:8080/grading/locations/2
        teacherRepository.deleteById(id);
    }
    
    @GetMapping("/{id}")
    public Teacher getTeacher(@PathVariable("id") Long id) {
        return teacherRepository.findById(id).get();
    }
}

如果我在实体类中取消注释, 我会收到以下错误。该错误看起来像是表/实体教师中的一列Section sectionAdvisoryTeachersectionAdvisory

java.sql.SQLSyntaxErrorException: Unknown column 'teacher0_.section_advisory_id' in 'field list'

对于如何正确构建它,我将不胜感激。

提前致谢。

标签: javaspringspring-boothibernatejpa

解决方案


推荐阅读