jpa 如何在没有@PreRemove的情况下删除实体之前添加一些逻辑?

mlnl4t2r  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(65)

我在我的项目中发现了一个问题。A有三个实体:CompanyBranch,Department,Employee。CompanyBranch和Departmen之间的关系是一对多,与Department和Employee相同。这里我的实体类:

@Entity
@Table(name = "COMPANY_BRANCH", uniqueConstraints = {
        @UniqueConstraint(name = "AddressUniqueConstraint", columnNames = {"COMPANY_BRANCH_CITY",
                "COMPANY_BRANCH_ZIP_CODE", "COMPANY_BRANCH_STREET", "COMPANY_BRANCH_COUNTRY"})
})
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class CompanyBranch {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Convert(
            converter = MoneyConverter.class
    )
    @Column(name = "COMPANY_BRANCH_BUDGET", length = 63)
    private Money budget;

    @Embedded
    @NotNull
    @AttributeOverrides({
            @AttributeOverride(name = "city",
                column = @Column(name = "COMPANY_BRANCH_CITY")),
            @AttributeOverride(name = "zipCode",
                column = @Column(name = "COMPANY_BRANCH_ZIP_CODE")),
            @AttributeOverride(name = "street",
                column = @Column(name = "COMPANY_BRANCH_STREET")),
            @AttributeOverride(name = "country",
            column = @Column(name = "COMPANY_BRANCH_COUNTRY"))
    })
    private Address companyBranchAddress;

    @NotNull
    @NotBlank(message = "Номер телефона не должен быть пустым")
    @Pattern(regexp = "^(\\+\\d{1,3}( )?)?((\\(\\d{1,3}\\))|\\d{1,3})[- .]?\\d{3,4}[- .]?\\d{4}$",
            message = "Неверный формат номера!")
    @Column(name = "COMPANY_BRANCH_PHONE_NUMBER", unique = true)
    private String phoneNumber;
}

字符串
部门名称:

@Entity
@Table(name = "DEPARTMENT")
@Getter
@Setter
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @NotBlank(message = "Название отдела не может быть пустым!")
    @Column(name = "DEPARTMENT_NAME")
    private String departmentName;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "LAST_MODIFIED")
    private Date lastModified;

    @NotNull
    @NotBlank(message = "Номер телефона не должен быть пустым")
    @Pattern(regexp = "^(\\+\\d{1,3}( )?)?((\\(\\d{1,3}\\))|\\d{1,3})[- .]?\\d{3,4}[- .]?\\d{4}$",
            message = "Неверный формат номера!")
    @Column(name = "DEPARTMENT_PHONE_NUMBER", unique = true)
    private String phoneNumber;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "COMPANY_BRANCH_ID", nullable = false)
    private CompanyBranch companyBranch;

    @PrePersist
    @PreUpdate
    protected void setDefaultLastModified(){
        lastModified = new Date();
    }

}


员工:

@Entity
@Table(name = "EMPLOYEE")
@Getter
@Setter
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Embedded
    private Name name;

    @Pattern(regexp = "^(\\+\\d{1,3}( )?)?((\\(\\d{1,3}\\))|\\d{1,3})[- .]?\\d{3,4}[- .]?\\d{4}$",
             message = "Неверный формат номера!")
    @NotNull
    @NotBlank(message = "Телефон не может быть пустым!")
    @Column(unique = true, name = "PHONE_NUMBER")
    private String phoneNumber;

    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name = "city",
                column = @Column(name = "HOME_CITY")),
            @AttributeOverride(name = "zipCode",
                column = @Column(name = "HOME_ZIP_CODE")),
            @AttributeOverride(name = "street",
                column = @Column(name = "HOME_STREET")),
            @AttributeOverride(name = "country",
                column = @Column(name = "HOME_COUNTRY"))
    })
    private Address homeAddress;

    @Email(message = "Неверный формат почты!")
    @NotNull
    @Column(unique = true, name = "EMAIL")
    private String email;

    @Temporal(value = TemporalType.DATE)
    @Column(name = "EMPLOYMENT_DATE", updatable = false)
    @CreationTimestamp
    private Date employmentDate;

    @BatchSize(size = 4)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "EMPLOYEE_STATUS_ID")
    private EmployeeStatus employeeStatus;

    @NotNull
    @Convert(
            converter = MoneyConverter.class
    )
    @Column(name = "SALARY", length = 63)
    private Money salary;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "DEPARTMENT_ID")
    private Department department;
}


当我删除部门时,我想同时更改这个部门中每个员工的状态,我想用@PreRemove annotation来做这件事,但我认为这不是最好的方法,因为EQUIPEStatus是一个实体类,所以我需要在实体类中注入spring逻辑。所以这是我管理问题的方式:

@Modifying(clearAutomatically = true, flushAutomatically = true)
    @Query(value = "UPDATE Employee e SET e.employeeStatus = " +
            "(SELECT es FROM EmployeeStatus es WHERE es.employeeStatus = 'FIRED'), " +
            "e.department = null " +
            "WHERE e.department = :department")
    void updateEmployeesStatusToFiredOnDelete(Department department);


这是部门服务中的方法:

@Transactional
    public void deleteDepartment(Department department) {
        if (department == null)
            throw new IllegalArgumentException("Illegal department for removal!");

        departmentRepository.updateEmployeesStatusToFiredOnDelete(department);
        departmentRepository.delete(department);
    }


但是当我删除公司分支时,我想同时删除其中的所有部门,员工的状态也应该改变。正如我已经说过的,我不认为@PreRemove可以帮助我解决这个问题。我正在考虑为公司分支创建一个新的@Query存储库,但我认为这太不方便了。也许有一些其他的解决方案来解决这个问题?也许我仍然可以使用@PreRemove在这里不知何故?

e5njpo68

e5njpo681#

1.部门删除和员工状态更改
在我看来,你应该使用@ translation在单个事务中执行这些操作。也就是说,正如你所建议的那样。当删除部门时出现错误时,应该回滚事务。
1.删除公司分支和部门
我不认为@PreRemove是最好的选择。我会简单地在一个事务中删除公司分支,公司分支的所有部门,并使用Repository和Spring Data更改员工状态。我认为这是一个更可读的解决方案。

相关问题