如何在使用 JPA 注释从多对多关系(带有额外列)中删除父级时自动删除孤儿级

问题描述 投票:0回答:1

我有 2 个实体(Post 和 Tag)使用连接表的中间实体(PostTag)映射到多对多关系(以便能够将附加列映射到连接表)。

Post
+----+--------+
| id | name   |
+----+--------+
|  1 | Post 1 |
|  2 | Post 2 |
+----+--------+

Tag
+----+--------+
| id | name   |
+----+--------+
|  1 | Tag  1 |
|  2 | Tag  2 |
+----+--------+

Post_Tag
+----+-----------------------+---------+--------+
| end_date                   | post_id | tag_id |
+----+-----------------------+---------+--------+
| 2020-10-27 13:44:17.045000 |       1 |      1 |
| 2020-10-27 13:44:17.045000 |       2 |      1 |
| 2020-10-27 13:44:17.057000 |       2 |      2 |
+----+-----------------------+---------+--------+

案例一: 当从 Post 表中删除 post(id=2) 时,有没有办法从 Tag 表中自动删除 tag(id=2)? Tag 表中的 tag(id=1) 不应被删除。

案例二: 当标签(id=2)和帖子(id=2)之间的关联被删除时,有没有办法从标签表中自动删除标签(id=2)?

@Entity()
@Table(name = "post")
public class Post {
    @Id
    @Column(name = "id")
    @Type(type = "uuid-char")
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private UUID id;

    private String title;

    @OneToMany(
            mappedBy = "post",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private Set<PostTag> tags = new HashSet<>();

    public Post() {
    }

    public Post(String title) {
        this.title = title;
    }

    //Getters and setters omitted for brevity

    public void addTag(Tag tag, ZonedDateTime zonedDateTime) {
        PostTag postTag = new PostTag(this, tag);
        postTag.setEndDate(zonedDateTime);
        tags.add(postTag);
    }

    public void removeTag(Tag tag) {
        for (Iterator<PostTag> iterator = tags.iterator();
             iterator.hasNext(); ) {
            PostTag postTag = iterator.next();

            if (postTag.getPost().equals(this) &&
                    postTag.getTag().equals(tag)) {
                iterator.remove();
                postTag.setPost(null);
                postTag.setTag(null);
            }
        }
    }
}

@Entity()
@Table(name = "tag")
public class Tag {
    @Id
    @Column(name = "id")
    @Type(type = "uuid-char")
    private UUID id;

    private String name;

    public Tag() {
    }

    public Tag(UUID id, String name) {
        this.id = id;
        this.name = name;
    }

    //Getters and setters omitted for brevity
}

@Embeddable
public class PostTagId implements Serializable {

    @Column(name = "post_id")
    @Type(type = "uuid-char")
    private UUID postId;

    @Column(name = "tag_id")
    @Type(type = "uuid-char")
    private UUID tagId;

    PostTagId() {}

    public PostTagId(UUID postId, UUID tagId) {
        this.postId = postId;
        this.tagId = tagId;
    }
    //Getters and setters omitted for brevity
}

@Entity()
@Table(name = "post_tag")
public class PostTag {
    @EmbeddedId
    private PostTagId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("postId")
    private Post post;

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId("tagId")
    private Tag tag;

    // extra column
    @Column(name = "end_date")
    private ZonedDateTime endDate;

    PostTag() {}

    public PostTag(Post post, Tag tag) {
        this.post = post;
        this.tag = tag;
        this.id = new PostTagId(post.getId(), tag.getId());
    }

    public PostTagId getId() {
        return id;
    }
    //Getters and setters omitted for brevity
}

Case 1:
public void deletePost(Post post) {
        postRepository.delete(post);
    }

Case 2:
public void removeTag(Post post, Tag tag) {
        post.removeTag(tag);
        postRepository.save(post);
    }
java hibernate jpa orm hibernate-mapping
1个回答
0
投票
private static ArrayList<Tag> tag = new ArrayList<Tag>();
public void removeTag() {
    for (int i = 0; i < tag.size(); i++) {
            System.out.println(i + " " + tag.get(i));
        }
        int removeTag = scanner.nextInt();
        if (removeTag <= tag.size()) {
            tag.remove(removeTag - 1);
        }
    }

试试这个。我立马说我还在读书不知道我的回答对不对..

© www.soinside.com 2019 - 2024. All rights reserved.