通过级联 OneToOne 删除清除 ManyToMany

问题描述 投票:0回答:1

我在 Hibernate 项目中遇到问题,我尝试删除 OneToOne 关系,但在 ManyToMany 关系中仍然有条目。

实体:

@Getter
@Setter
@Entity
public class Employee implements Serializable {

    @Id
    Long id;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "employeeId", cascade = CascadeType.ALL, orphanRemoval = true)
    private AppUser appUser;
    
    // some more basic fields

}

@Getter
@Setter
@Entity
public class AppUser implements Serializable {

    @Id
    Long id;

    @OneToOne
    @JoinColumn(name = "employeeId")
    @NotNull
    private Employee employeeId;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "AppUserPermission", joinColumns = @JoinColumn(name = "appUserId"), inverseJoinColumns = @JoinColumn(name = "permissionId"))
    private Set<Permission> permissions = new HashSet<>();
    
    // some more basic fields
}

@Getter
@Setter
@Entity
public class Permission implements Serializable {

    @Id
    Long id;
    
    // some more basic fields
}

数据库:

CREATE TABLE IF NOT EXISTS Employee
(
    id bigint NOT NULL,
    CONSTRAINT pk_Employee PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS AppUser
(
    id bigint NOT NULL,
    employeeId bigint NOT NULL,
    CONSTRAINT pk_AppUser PRIMARY KEY (id),
    CONSTRAINT uq_AppUser_employeeId UNIQUE (employeeId),
    CONSTRAINT fk_AppUser_employeeId FOREIGN KEY (employeeId)
        REFERENCES Employee (id) MATCH SIMPLE
        ON UPDATE RESTRICT
        ON DELETE RESTRICT
);

CREATE TABLE IF NOT EXISTS Permission
(
    id bigint NOT NULL,
    CONSTRAINT pk_Permission PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS AppUserPermission
(
    appUserId bigint NOT NULL,
    permissionId bigint NOT NULL,
    CONSTRAINT pk_AppUserPermission PRIMARY KEY (appUserId, permissionId),
    CONSTRAINT fk_AppUserPermission_appUserId FOREIGN KEY (appUserId)
        REFERENCES AppUser (id) MATCH SIMPLE
        ON UPDATE RESTRICT
        ON DELETE RESTRICT,
    CONSTRAINT fk_UserPermission_permissionId FOREIGN KEY (permissionId)
        REFERENCES Permission (id) MATCH SIMPLE
        ON UPDATE RESTRICT
        ON DELETE RESTRICT
);

当我现在尝试从员工中删除用户条目时,该用户没有权限,它会按预期工作 - 用户已从数据库中删除:

Employee employee = session.find(Employee.class, employeeId);

// user has no permission(s)
Assert.assertTrue(employee.getAppUser().getPermissions().isEmpty());

employee.setAppUser(null);
session.update(employee);
session.flush();

也可以通过员工删除权限 - 数据库连接中的条目已被删除,权限仍然可用:

Employee employee = session.find(Employee.class, employeeId);

// user has permission(s)
Assert.assertFalse(employee.getAppUser().getPermissions().isEmpty());

employee.getAppUser().getPermissions().clear();
session.update(employee);
session.flush();

// this would also work now, but I wan't prevent two updates if possible
employee.setAppUser(null);
session.update(employee);
session.flush();

但如上所述,我想在一次更新中做到这一点:

Employee employee = session.find(Employee.class, employeeId);

// user has permission(s)
Assert.assertFalse(employee.getAppUser().getPermissions().isEmpty());

employee.setAppUser(null);
session.update(employee);
session.flush();

有人知道如何解决吗?

我知道如果我将 AppUserPermission 表上的删除级联选项从限制更改为级联,它会起作用,但我想知道如果没有这个选项,Hibernate 是否能够处理它。从现在开始,JPA 按正确的顺序处理所有级联删除,即使数据库的选项受到限制也是如此。

java hibernate many-to-many
1个回答
0
投票

你可以在

AppUser
课上尝试这个吗?

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "AppUserPermission", joinColumns = @JoinColumn(name = "appUserId"), inverseJoinColumns = @JoinColumn(name = "permissionId"))
private Set<Permission> permissions = new HashSet<>();

由于您使用指定级联

CascadeType.ALL
,当删除
AppUser
条目时,相关权限也应该自动删除。

© www.soinside.com 2019 - 2024. All rights reserved.