Bas*_*tor 6 java mysql jpa spring-data-jpa spring-boot
也许这是一个过于简单的问题,但是当我尝试删除用户实体时,我遇到了异常.
用户实体:
@Entity
@Table(name = "users")
public class User
{
@Transient
private static final int SALT_LENGTH = 32;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@NotNull
private String firstName;
@NotNull
private String lastName;
@Column(unique = true, length = 254)
@NotNull
private String email;
// BCrypt outputs 60 character results.
@Column(length = 60)
private String hashedPassword;
@NotNull
private String salt;
private boolean enabled;
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(updatable = false)
private Date createdDate;
Run Code Online (Sandbox Code Playgroud)
我有一个实体类,它引用具有外键的用户.我想要发生的是,当用户被删除时,任何PasswordResetToken引用该用户的对象也将被删除.我怎样才能做到这一点?
@Entity
@Table(name = "password_reset_tokens")
public class PasswordResetToken
{
private static final int EXPIRATION_TIME = 1; // In minutes
private static final int RESET_CODE_LENGTH = 10;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String token;
@OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
@JoinColumn(nullable = false, name = "userId")
private User user;
private Date expirationDate;
Run Code Online (Sandbox Code Playgroud)
我得到的例外归结为 Cannot delete or update a parent row: a foreign key constraint fails (`heroku_bc5bfe73a752182`.`password_reset_tokens`, CONSTRAINT `FKk3ndxg5xp6v7wd4gjyusp15gq` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`))
我想避免PasswordResetToken在父实体中添加引用,因为User不应该知道任何事情PasswordResetToken.
在没有创建双向关系的情况下,在JPA级别上是不可能的.您需要在User类中指定级联类型.User应该是关系的所有者,它应该提供有关如何处理相关的信息PasswordResetToken.
但是如果你不能有双向关系,我建议你直接在模式生成SQL脚本中设置关系.
如果您通过SQL脚本创建架构而不是通过JPA自动生成(我相信所有严肃的项目必须遵循此模式),您可以在ON DELETE CASCADE那里添加约束.
它会看起来像这样:
CREATE TABLE password_reset_tokens (
-- columns declaration here
user_id INT(11) NOT NULL,
CONSTRAINT FK_PASSWORD_RESET_TOKEN_USER_ID
FOREIGN KEY (user_id) REFERENCES users (id)
ON DELETE CASCADE
);
Run Code Online (Sandbox Code Playgroud)
以下是有关如何将数据库迁移工具与spring boot一起使用的文档.以下是有关如何从hibernate生成模式脚本的信息(这将简化编写自己脚本的过程).
父实体:
@OneToOne
@JoinColumn(name = "id")
private PasswordResetToken passwordResetToken;
Run Code Online (Sandbox Code Playgroud)
子实体:
@OneToOne(mappedBy = "PasswordResetToken", cascade = CascadeType.ALL, orphanRemoval = true)
private User user;
Run Code Online (Sandbox Code Playgroud)
如果您希望对客户端隐藏 Password 实体,您可以编写自定义响应并将其隐藏。或者,如果您想通过使用忽略它@JsonIgnore
如果您不想要父实体(用户)中的引用,那么您必须覆盖默认方法Delete()并编写逻辑以首先查找和删除PasswordResetToken,然后是User。
| 归档时间: |
|
| 查看次数: |
9502 次 |
| 最近记录: |