Hibernate在从集合中删除实体时执行额外的SELECT [重复]

pgccezyw  于 2023-10-23  发布在  其他
关注(0)|答案(1)|浏览(117)

此问题已在此处有答案

Hibernate Delete query(5个答案)
上个月关门了。
我试图从Set中删除实体,但当我这样做时,hibernate生成的选择比我预期的要多(我使用的是spring data jpa)。
下面是我的代码-CompanyBranch实体:

@Entity
@Table(name = "COMPANY_BRANCH")
@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")
    private String phoneNumber;

    @OneToMany(mappedBy = "companyBranch", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Department> departments = new HashSet<>();

    public void addDepartment(Department department) {
        this.departments.add(department);
        department.setCompanyBranch(this);
    }

    public void removeDepartment(Department department) {
        department.setCompanyBranch(null);
        departments.remove(department);
    }
}

部门实体:

@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", insertable = false, updatable = false)
    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")
    private String phoneNumber;

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

    @OneToMany(mappedBy = "department", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<Employee> employees = new HashSet<>();

    public void addEmployee(Employee employee) {
        this.employees.add(employee);
        employee.setDepartment(this);
    }

    public void removeEmployee(Employee employee) {
        this.employees.remove(employee);
        employee.setDepartment(null);
    }

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

    @PreRemove
    protected void changeEmploysStatus() {
        this.employees.forEach(employee -> employee.getEmployeeStatus().setEmployeeStatus(EEmployeeStatus.FIRED));
    }
}

这就是我从Set中删除部门的方法

CompanyBranch companyBranch = companyBranchService.getCompanyBranchById(companyBranchId);
Department department = departmentService.getDepartmentById(depId);
companyBranchService.removeDepartment(companyBranch, department);

移除方法:

public void removeDepartment(CompanyBranch companyBranch, Department department) {
        companyBranch.removeDepartment(department);
        companyBranchRepository.saveAndFlush(companyBranch);
    }

以下是Hibernate生成的查询:

Hibernate: 
    select
        c1_0.id,
        c1_0.company_branch_budget,
        c1_0.company_branch_city,
        c1_0.company_branch_country,
        c1_0.company_branch_street,
        c1_0.company_branch_zip_code,
        c1_0.company_branch_phone_number 
    from
        company_branch c1_0 
    where
        c1_0.id=?
Hibernate: 
    select
        d1_0.id,
        d1_0.company_branch_id,
        d1_0.department_name,
        d1_0.last_modified,
        d1_0.department_phone_number 
    from
        department d1_0 
    where
        d1_0.id=?
Hibernate: 
    select
        d1_0.company_branch_id,
        d1_0.id,
        d1_0.department_name,
        d1_0.last_modified,
        d1_0.department_phone_number 
    from
        department d1_0 
    where
        d1_0.company_branch_id=?

为什么Hibernate会生成最后一个SELECT查询?它是否连接到保存方法?或者其他原因?我想这是因为保存操作,但我不确定这一点。

vwoqyblh

vwoqyblh1#

正确的解释:Hibernate删除查询
你可以通过它得到一个正确的想法。
如果需要,可以编写本机查询来避免选择查询。

@Modifying
@Query(nativeQuery = true, value = "DELETE FROM some_table WHERE id = :id")
void deleteById(@Param("id") Integer id);

相关问题