问题描述
我的应用程序存在以下问题。
定义: 我有3张桌子。用户、密码和确认令牌。用户表是父表。密码表和确认令牌表是与用户表具有一对一关系的子表。用户和确认表 ID 作为外键存储在用户表中。
问题:
当用户激活他的帐户时,应从确认令牌表中删除确认令牌行。因此,用户表中的列也应该被删除。
我的收获: 使用以下方案,发生的情况是,当我删除确认令牌时,整个用户行数据也会被删除,但密码行数据不会被删除。我想要的是,当删除确认令牌时,只应删除用户表中的相应行和外键列。
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userId;
private String username;
private String email;
private UserStatus status;
private LocalDateTime registerDate;
private LocalDateTime lastLoginDate;
@OnetoOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PASSWORD_ID",referencedColumnName = "passwordId")
private UserPasswords userPassword;
@OnetoOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ACCOUNT_CONFIRMATION_TOKEN_ID")
private ConfirmationToken confirmationToken;}
@Entity
public class ConfirmationToken {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int tokenId;
private String confirmationToken;
private LocalDateTime creationDate;
@OnetoOne(fetch = FetchType.LAZY,mappedBy = "confirmationToken",cascade=CascadeType.REMOVE,optional=true)
private User user;
}
@Entity
@Table(name = "USER_PASSWORDS")
public class UserPasswords {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int passwordId;
private String password;
private String beforePassword;
private int wrongPasswordTrial;
private LocalDateTime wrongPasswordDate;
private LocalDateTime lastPasswordUpdate;
@OnetoOne(fetch = FetchType.LAZY,mappedBy = "userPassword")
private User user;
解决方法
发生这种情况是因为设置了 cascade=CascadeType.REMOVE
。当相应的 User
行被删除时,这会设置 ConfirmationToken
实体被删除。
使用 DELETE 语句无法仅删除列的值。这只能通过 UPDATE 语句完成。 DELETE 将始终删除整行。
为了实现您想要的效果,您可以将连接列移动到 ConfirmationToken
表,方法是将 @JoinColumn
注释移动到 ConfirmationToken
实体中的映射。这里:
@OneToOne(fetch = FetchType.LAZY,mappedBy = "confirmationToken",optional=true)
@JoinColumn(name = "ACCOUNT_CONFIRMATION_TOKEN_ID")
private User user;
这会将您要删除的列移动到将删除整行的表中。这完全不需要 UPDATE 语句。