【问题标题】:How can I map employees with schedules in Many-To-Many (or One-To-Many) Relationships with Spring Boot JPA如何使用 Spring Boot JPA 将员工映射到多对多(或一对多)关系中的日程安排
【发布时间】:2025-12-11 12:15:01
【问题描述】:

我找不到将某些实体映射到我的 SQL 表的方法。我有一个 EMPLOYEES 表(带有 PK employee_id)、一个 DAYS_OF_WEEK 表(带有 PK day_of_week_id)和一个 EMPLOYEES_SCHEDULES 表(带有employee_id、day_of_week_id 和 start_time 的复合 PK,是上述表的前两个属性 FK,而 end_time 是唯一的非PK属性)。

EMPLOYEES
PK  employee_id
    role_id     FK

DAYS_OF_WEEK
PK  day_of_week_id
    name

EMPLOYEES_SCHEDULES
PK | employee_id    FK
   | day_of_week_id FK
   | start_time
     end_time

我必须遵循的类图表明 Employee 有 0 个或多个 EmployeeSchedule 对象相关联,而 EmployeeSchedule 有 1 个或多个 DayOfWeek 对象相关联。所以,Java 中的类应该是这样的:

@Entity
@Table(name = "EMPLOYEES")
public class Employee {
    @Id
    @Column(name = "employee_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int employeeId;

    @OneToOne
    @JoinColumn(name = "role_id", referencedColumnName = "role_id")
    private Role role;
    
    // I don't know how to map this
    private List<EmployeeSchedule> employeeSchedule;
}

@Entity
@Table(name = "EMPLOYEES_SCHEDULES")
public class EmployeeSchedule {
    @Id
    @Column(name = "start_time")
    private LocalDate startTime;

    @Basic
    @Column(name = "end_time")
    private LocalDate endTime;
    
    // I don't know how to map this
    private List<DayOfWeek> dayOfWeek;
}

@Entity
@Table(name = "DAYS_OF_WEEK")
public class DayOfWeek {
    @Id
    @Column(name = "day_of_week_id")
    private byte dayId;

    @Basic
    @Column(name = "name")
    private String name;
}   

我知道 DayOfWeek 可能会替换为枚举,但这不是本文的重点。如果可能,请不要建议更改类图的结构,因为我必须严格使用它(关系也不应该是双向的)。但是我制作的表格是否足以映射类?如果是这样,我该如何映射它们?

【问题讨论】:

    标签: java spring-boot jpa


    【解决方案1】:

    你添加这样的东西:

     @OneToMany(cascade = CascadeType.ALL, mappedBy = "employeeSchedule")
    private List<DayOfWeek> dayOfWeek=new ArrayList<>();
    

    到您的日期列表。 然后在实体 DayOfWeek 中添加属性为:

        @JoinColumn(name = "NAME_OF_COLUMN", referencedColumnName = "NAME_OF_REFRENECED_COLUMN")
        @ManyToOne(optional = false)
        private EmployeeSchedule employeeSchedule=new ArrayList<>();
    

    注意,实体 DayOfWeek 中的属性名称需要与实体 EmployeeSchedule 中“mappedBy”的定义相同。此外,您需要初始化列表。 我现在注意到您对 Employee 实体有同样的问题。 如前所述,您必须在列表中添加注释。由于没有 ZeroToMany 注释,因此您使用 OneToMany 因为此 注释描述了连接 beetwen 实体类,而不是数据库。您不能将 0 个实体连接到多个实体。所以下一个注释描述了表之间的连接。 将此添加到列表中:

     @OneToMany(cascade = CascadeType.ALL, mappedBy = "employee")
    private List<EmployeeSchedule> employeeSchedule=new ArrayList<>();
    

    并将其添加到 Employee 实体:

    @JoinColumn(name = "NAME_OF_COLUMN", referencedColumnName = "NAME_OF_REFRENECED_COLUMN")
    @ManyToOne(optional = false)
    private Employee employee;
    

    【讨论】:

    • 我想我按照你说的做了,但我遇到了这个错误:无法在 org.hibernate.mapping.Table(employees_schedules) 及其相关的超级表和辅助表中找到具有逻辑名称的列:day_of_week_id是因为它们在两个表中具有相同的名称吗?
    • 绝对不是,我总是使用相同命名的列(主键和外键)并且没有任何问题。您确定这是数据库表中列的名称吗?很难像这样猜测它可能是什么。我不知道您使用的是哪个数据库,但请检查 CAPS。
    • 是的。如果不是,IntelliJ 会告诉我。我会看看我还能做什么,谢谢你的帮助!
    • 我知道发生了什么。我实际上正在查看解释和数据库,有一件事让我印象深刻。如果在表 EmployeeSchedule 中有复杂的 primaryKey,其值为 dayOfWeak、employee 和 startTime,那么一个 @Entity EmployeeSchedule 怎么能拥有更多?此外,excpetion 解释了在您的实体 bean 中没有与数据库中的列相关的属性
    • 您的意思是一个员工元组如何在employees_shededules 中链接多个元组?由于复合键,两个不同的员工可以在同一时间和同一天开始工作。我认为表结构有效,你会改变什么?