我在 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 按正确的顺序处理所有级联删除,即使数据库的选项受到限制也是如此。
你可以在
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
条目时,相关权限也应该自动删除。