【问题标题】:JPA: How to remove user and all references from other tables?JPA:如何从其他表中删除用户和所有引用?
【发布时间】:2018-01-26 16:17:03
【问题描述】:

当我从users 表中删除一个用户时,他的所有posts 和任何comments 都应该被删除。

模型如下所示:

@Data
@Entity @Table(name = "users")
public class BlogUser {

    @Id
    private String userName;
    private String password;
    private String email;

    @Enumerated(EnumType.STRING)
    private Role role;

    private boolean enabled;
}

post 实例引用了所属用户:

@Data
@Entity @Table(name = "posts")
public class Post {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String postText;

    @ManyToOne(cascade = CascadeType.ALL)
    private BlogUser user;

    private LocalDateTime createdDate;
}

同样的情况也适用于 cmets。

现在当我想执行删除时,我收到了这个错误:

org.postgresql.util.PSQLException:错误:更新或删除表“users”违反了表“posts”上的外键约束“fkqdk379brhxkbj4c8qenbuu85l”

DB 是 Postgres。我尝试使用@ManyToOne(cascade = CascadeType.ALL),但没有帮助。

更新:

这个想法是我想保留表的当前架构。
无需将帖子和/或 cmets 添加到 BlogUser 类。

【问题讨论】:

  • 在休眠方面似乎没问题,您的数据库模式是从休眠类生成的还是相反?还是都手动创建?
  • @Tapaka DB 是手动创建的。以及应用程序生成的所有表。我正在使用 Spring Boot 应用程序。

标签: postgresql hibernate jpa sql-delete cascade


【解决方案1】:

您还需要将级联添加到BlogUser 侧,以便对其进行删除以级联到PostComment

将这样的内容添加到您的 BlogUser 类中:

@Getter
@OneToMany(cascade=CascadeType.ALL, mappedBy="user")
private Collection<Post> posts = new HashSet<>();

@Getter
@OneToMany(cascade=CascadeType.ALL, mappedBy="user")
private Collection<Comment> comments = new HashSet<>();

【讨论】:

  • 对于更新:在 JAVA 方面,可能性是有限的。我的回答不应该触及架构。如果您不想按照Tapaka 的建议进行操作,那么您可以随时通过user 获取所有posts / comments 并在删除user 之前删除它们。
  • 我今天提出了相同的解决方案。并让这些数据的所有删除都是事务性的。
【解决方案2】:

您的问题很可能来自您没有在表上声明 ON CASCADE 的事实。基本上,您需要删除用户/帖子和帖子/ cmets 之间的 id 约束,并在最后添加 ON CASDADE DELETE 重新创建它们。 This 应该可以帮到你。

或者,如果您不想这样做,您显然可以删除用户 ID 与您想要的匹配的帖子/评论,然后删除所述用户。如果您更喜欢此解决方案,This 也会对您有所帮助。

【讨论】:

  • 我可以使用您的任何解决方案,但可以通过 JPA 从 Java 代码设置它,而不是手动修改数据库吗?
  • @nazar_art 如果您不想修改当前架构,则必须使用第二个选项 IMO。使用 JPA 创建一个从 Java 代码调用的查询,它应该可以正常工作。
  • @nazar_art 不,你不能让它既自动级联,又在 BlogUser 中没有依赖实体,也不能手动修改模式。您必须使用两种解决方案中的任何一种,或者手动运行删除查询。只要确保@ManyToOne 关联中没有CascadeType.ALL,否则它将递归清除所有这三个表。
猜你喜欢
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多