持久化超类,并稍后在子类中使用Spring Boot Data JPA继承更新它,没有重复



我试图使用spring启动数据JPA继承来实现以下内容:

  • 创建并保存超类实体(Staff)中的对象
  • 基于父类实体创建的现有员工,创建子类实体(TeachingStaff)对象,更新它并将其保存在员工表中,不重复。

下面是一个示例代码:

SQL:

CREATE TABLE Staff (
staff_id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(50) UNIQUE NOT NULL,
salary DECIMAL(10,2) NOT NULL
);
CREATE TABLE TeachingStaff (
staff_id INT PRIMARY KEY,
department VARCHAR(50) NOT NULL,
FOREIGN KEY (staff_id) REFERENCES Staff(staff_id)
);

Java:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Staff {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "staff_id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "email")
private String email;
@Column(name = "salary")
private Double salary;
// constructors, getters and setters
}
@Entity
public class TeachingStaff extends Staff {
@Column(name = "department")
private String department;
@Column(name = "subject_taught")
private String subjectTaught;
// constructors, getters and setters
}

人员存储库:

@Repository
public interface StaffRepo extends JpaRepository<Staff, Long> {
Optional<Staff> findByEmail(String email);
}

TeachingStaff存储库:

@Repository
public interface TeachingStaffRepo extends JpaRepository<TeachingStaff, Long> {}

添加和更新一个新人员(为了简洁,我省略了服务层):

@Bean
CommandLineRunner run(StaffRepo staffRepo, TeachingStaffRepo teachingStaffRepo) {
return args -> {
// Adding a new staff
Staff newStaff = new Staff("John Doe", "john.doe@email.com", 2000.0);
staffRepo.save(newStaff);
// Retrieving and updating an existing staff
Staff existingStaff = staffRepo.findByEmail("john.doe@email.com").orElseThrow();
TeachingStaff newTeachingStaff = new TeachingStaff();
newTeachingStaff.setId(existingStaff.getId());
newTeachingStaff.setName(existingStaff.getName());
newTeachingStaff.setEmail(existingStaff.getEmail());
newTeachingStaff.setSalary(existingStaff.getSalary());
newTeachingStaff.setDepartment("Mathematics");
newTeachingStaff.setSubjectTaught("Calculus");
teachingStaffRepo.save(newTeachingStaff);
};
}

这几天我一直在尝试不同的方法,但还没有运气。我尝试了所有的策略@Inheritance@MappedSuperclass但它们没有像预期的那样工作。

创建与上面相同的SQL模式的唯一方法是使用InheritanceType。加入。但问题是,当我想更新员工并使他成为教学人员时,会在员工表中插入重复的记录。

我读到这可以通过分离检索对象(existingStaff)来实现,但这并没有解决重复问题。

在Spring Boot Data JPA中有解决这个问题的方法吗?

经过几天的搜索和测试不同的方法,我得出的结论是组成是我的面向对象到关系数据库设计中唯一的内置解决方案。

另一个解决方案是在子类的存储库中添加自定义方法并实现自定义SQL(或JPQL)查询,如下所示:

@Modifying
@Query(value = "INSERT INTO teaching_staff " +
"(staff_id, department, subject_taught)" +
"   VALUES (:#{#t.id}, :#{#t.department}, :#{#t.subjectTaught})", nativeQuery = true)
@Transactional
void makeTeachingStaff(@Param("t") TeachingStaff teachingStaff);

最新更新