我在用户和组之间建立了多对多关系,并在连接表中添加了其他列。它看起来像这样:
当我删除一个用户时,它应该从 user_to_group 中删除他的所有引用(这有效)并且他创建的所有组应该保留并将它们的 created_by 字段更新为 NULL(这不会发生,所有条目都被删除).
模式的 DDL:
CREATE TABLE user (
user_id int NOT NULL AUTO_INCREMENT,
first_name varchar(100) NOT NULL,
last_name varchar(100) NOT NULL,
username varchar(100) NOT NULL,
email_address varchar(100) UNIQUE NOT NULL,
phone_number varchar(100) NOT NULL,
password varchar(255) NOT NULL,
notification_type varchar(30) NOT NULL DEFAULT "email",
date_created datetime NOT NULL,
is_active bool NOT NULL DEFAULT false,
CONSTRAINT user_pk PRIMARY KEY (user_id)
);
CREATE TABLE `group` (
group_id int NOT NULL AUTO_INCREMENT,
name varchar(100) NULL,
date_created datetime NOT NULL,
is_private bool NOT NULL DEFAULT false,
created_by int NULL,
CONSTRAINT group_pk PRIMARY KEY (group_id),
CONSTRAINT group_user_fk FOREIGN KEY(created_by)
REFERENCES user (user_id) ON DELETE SET NULL
);
CREATE TABLE user_to_group (
user_id int NOT NULL,
group_id int NOT NULL,
user_type_id int NOT NULL,
is_blocked bool NOT NULL DEFAULT false,
CONSTRAINT user_to_group_pk PRIMARY KEY (user_id,group_id),
CONSTRAINT user_to_group_group_fk FOREIGN KEY(group_id)
REFERENCES `group` (group_id),
CONSTRAINT user_to_group_user_type_fk FOREIGN KEY(user_type_id)
REFERENCES user_type (id),
CONSTRAINT user_to_group_user_fk FOREIGN KEY(user_id)
REFERENCES user (user_id)
);
用户实体:
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "username",
unique = true)
private String username;
@Column(name = "email_address",
unique = true)
private String emailAddress;
@Column(name = "phone_number")
private String phoneNumber;
@Column(name = "password")
private String password;
@Column(name = "notification_type",
insertable = false)
private String notificationType = "email";
@Column(name = "date_created")
private Date dateCreated;
@Column(name = "is_active",
insertable = false)
private Boolean active = false;
@OneToMany(
mappedBy = "user",
cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.REFRESH, CascadeType.PERSIST},
orphanRemoval = true
)
private List<UserGroup> groups;
}
集团实体:
@Entity
@Table(name = "`group`")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "group_id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "date_created")
private Date dateCreated;
@Column(name = "is_private",
insertable = false)
private Boolean privateG = false;
@OneToOne(fetch = FetchType.LAZY,
cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.REFRESH, CascadeType.PERSIST},
orphanRemoval = true)
@JoinColumn(name = "created_by")
private User createdBy;
@OneToMany(
mappedBy = "group",
cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.REFRESH, CascadeType.PERSIST},
orphanRemoval = true
)
private List<UserGroup> users = new ArrayList<>();
}
用户组(连接表):
@Entity
@Table(name = "user_to_group")
public class UserGroup {
@EmbeddedId
private UserGroupId id;
@ManyToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
@MapsId("userId")
@JoinColumn(name = "user_id", insertable = false, updatable = false)
private User user;
@ManyToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
@MapsId("groupId")
@JoinColumn(name = "group_id", insertable = false, updatable = false)
private Group group;
@Column(name = "is_blocked",
insertable = false)
private boolean isBlocked = false;
}
忽略连接表上的 user_type_id 字段。如果我在工作台上删除了一个用户,它会按预期工作(created_by 字段更新为 NULL)。但是如果我使用这个:
@Override
@Transactional
public User deleteUser(Long id) {
Optional<User> userToDelete = userRepository.findById(id);
userToDelete.ifPresent(user -> userRepository.delete(user));
return userToDelete.orElseThrow(() -> new UserNotFoundException("User not found"));
}
组表中的整行被删除。我做错了什么?
最佳答案
@ManyToOne(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
@MapsId("groupId")
@JoinColumn(name = "group_id", insertable = false, updatable = false)
private Group group;
排除 CascadeType.REMOVE
并且组将保持不变。
关于java - 多对多删除集 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52275087/