【问题标题】:Many to many on the same Entity同一实体上的多对多
【发布时间】:2019-06-20 03:07:21
【问题描述】:

我想创建一个类似 instagram 的应用程序。因此,用户应该拥有关注的用户列表以及关注他的用户列表。
这是我到目前为止所做的:

@ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
})
@JoinTable(name = "following_followers",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "followedby_id")
)
private List<User> followers;

@ManyToMany(cascade = {
        CascadeType.PERSIST,
        CascadeType.MERGE
})
@JoinTable(name = "following_followers",
        joinColumns = @JoinColumn(name = "followedby_id"),
        inverseJoinColumns = @JoinColumn(name = "user_id")
)
private List<User> following;

我检查了this 的帖子,并按照那边的好答案完成了它,但我不太确定这是否有效。

【问题讨论】:

  • 并且您没有说什么“不起作用”,也没有解释为什么要为 2 个不同的目的重用连接表。如果您的意思是这些关系是双向关系的两端,那么您将mappedBy 放在一侧。全部在 JPA 文档中

标签: java spring hibernate jpa relational-database


【解决方案1】:

many-to-many关联由Hibernate管理时,你不能自己控制连接表following_followers。例如,您不能使用 Hibernate 从表中删除记录。

在某些情况下many-to-many 关联可能有效,但我不确定这是您的情况。例如,想象一下您是如何设法删除用户的关注者的。

您可以尝试另一种方法:为以下关系添加单独的实体

@Enity
class Following {

  @ManyToOne(fetch = FetchType.LAZY)
  User from;

  @ManyToOne(fetch = FetchType.LAZY)
  User to;

}

您还可以添加唯一约束:(from, to) 可以是合适的。

【讨论】:

  • 所以你的建议是我应该创建另一个类和一个表,在其中记录从 - 到关系?
  • @StrahinjaRodic 是的。而且你已经有了following_followers 的桌子。并且所有有追随者的操作都最好使用Following(而不是User)来执行。最好在User 中没有Following 关联(字段)。
【解决方案2】:

这是我为您解决问题的方法。 用户类:

@Entity
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;

    private String name;

    @OneToMany(mappedBy="to")
    private List<Followers> followers;

    @OneToMany(mappedBy="from")
    private List<Followers> following;

    public User() {}

    public User(String name) {
        this.name = name;
    }

}

如您所见,用户类引用了正在关注的用户和他关注的用户。

@Entity
public class Followers {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long id;

    @ManyToOne
    @JoinColumn(name="from_user_fk")
    private User from;

    @ManyToOne
    @JoinColumn(name="to_user_fk")
    private User to;

    public Followers() {};

    public Followers(User from, User to) {
        this.from = from;
        this.to = to;
    }
}

followers 类包含两个用户之间的关系,当然您可能需要向该类添加更多信息,例如“from”何时开始跟随“to”。

如果您想获得用户的关注者/关注者,您只需调用相应的 getter。

【讨论】:

  • 最好不要使用User来处理Followers。甚至不要在UserFollowers 中提供关联。
  • 我同意你的观点,你应该为关注者创建一个存储库,其中包含所有相关查询,例如关注者的数量、我是否关注此人等等......但正如我从他想要的问题中理解的那样一类中的东西,所以如果你想要一类中的东西,这就是解决方案。
  • @v.ladynev 为什么在 Followers 类中使用 User 是不正确的?
  • @gmexo 我的评论不是关于Followers 班级,而是关于User 班级。最好不要在 User 类中提及 Followers
猜你喜欢
  • 2019-03-08
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
相关资源
最近更新 更多