سؤال

أحاول تصميم نوع ما من العلاقة بين المستخدم والمستخدم، مثل "المستخدم أ يتبع المستخدم ب" و"المستخدم أ يريد أن يكون صديق المستخدم ب".

لدي فئة مستخدم، وطريقة تصميمها تبدو كما يلي:

@Entity
public class User{
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> followers;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> following;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> friendRequests;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> requesting;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> friends;

}

أنا أواجه مشكلتين:

  • السبات يعطيني لا يمكن جلب أكياس متعددة في وقت واحد مشكلة
  • لقد بحثت عبر الإنترنت، وطلب الناس إزالة FetchType.EAGER أو تغييره إلى Set بدلاً من List، ولكن هذا أدى إلى لا يحتوي الحقل على قيمة افتراضية

لدي شعور بأن العلاقة لم يتم تعريفها بشكل صحيح، ويجب أيضًا أن أرى المزيد من الجداول، لأنني الآن أرى فقط جدول المستخدم وجدول User_User.


تحديث

ما يلي ينشئ 3 جداول، الأصدقاء، المتابعين، والطالبين.هل هذا مُحسّن إلى حد ما مقارنة بـ 5 جداول؟وهل هناك أي ميزة لهذا مقارنة بما اقترحه السيد J4mes؟

@ManyToMany
@JoinTable(name = "followers", joinColumns = @JoinColumn(name = "followerId"), inverseJoinColumns = @JoinColumn(name = "userId"))
private List<User> followers;
@ManyToMany
@JoinTable(name = "followers", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "followerId"))
private List<User> following;
@ManyToMany
@JoinTable(name = "friends", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "friendId"))
private List<User> friends;
@ManyToMany
@JoinTable(name = "requesters", joinColumns = @JoinColumn(name = "requesterId"), inverseJoinColumns = @JoinColumn(name = "userId"))
private List<User> friendRequests;
@ManyToMany
@JoinTable(name = "requesters", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "requesterId"))
private List<User> requesting;
هل كانت مفيدة؟

المحلول

بادئ ذي بدء، لتنفيذ الميزة الخاصة بك، يجب عليك استخدام @ManyToMany بدلاً من @OneToMany.يجب أن تبدو هذه:

@Entity
public class User implements Serializable {
   @ManyToMany(mappedBy="followers")
   @JoinTable(name="followingTable")
   private Set<User> following;
   @ManyToMany
   @JoinTable(name="followerTable")
   private Set<User> followers;
   @ManyToMany(mappedBy="friendRequests")
   @JoinTable(name="requestingTable")
   private Set<User> requesting;
   @ManyToMany
   @JoinTable(name="friendRequestTable")
   private Set<User> friendRequests;
   @ManyToMany
   private Set<User> friends;
}

علاقاتك تبدو وكأنها علاقات ثنائية الاتجاه بالنسبة لي.إذا كنت تستخدم @OneToMany, ، هذا يعني انه C has 2 followers A and B = A and B only follows C.ومع ذلك، فالحقيقة هي أنه يمكن لشخص واحد أن يتبع العديد من الأشخاص، ويمكن أن يتبع شخص واحد العديد من الأشخاص.بعبارة أخرى، A and B can also follow D.

الى جانب ذلك، لا ينبغي أن تستخدم cascadeType.ALL على الاطلاق.تعني هذه السياسة المتتالية أنه إذا قام مستخدم واحد بحذف حسابه وقمت بحذف الإدخال المقابل في قاعدة البيانات، فسيتم حذف جميع أصدقائه، وما إلى ذلك.سيتم حذفها أيضًا.

نصائح أخرى

سيؤدي الإسبات إلى إنشاء جدول واحد فقط لكيان المستخدم ، وأفترض وجود جدول مرجعي مشترك لعلاقة المستخدم بالمستخدم.قد يكون الحل البديل لوجود جداول مختلفة هو وجود كيانات مختلفة تم إعدادها للعلاقات المختلفة ، أي

كيان المستخدم Genacodicetagpre

كيان تابع Genacodicetagpre

بالنسبة لجلب EAGER ، قد ترغب في الواقع أن يكون كل هؤلاء كسالى ، نظرًا لحقيقة أنه اعتمادًا على كيفية إعداد قاعدة البيانات الخاصة بك ، قد تكون كل هذه الأحمال الشديدة مكلفة للغاية.فقط عندما يريد المستخدم تحميل المتابعين على المستخدمين ، أود جلبهم.

افصل ال User من Friends حاول إنشاء جدول يحتوي على عمودين على الأقل لتعيين User_ID لجميع له Friends_IDs والذي هو في الأساس إشارة إلى User_ID

أيضًا EAGER سيتم تحميل الجميع البيانات بمجرد الاتصال بها في المرة الأولى.يعني أنه سيتم تحميل جميع المستخدمين وأصدقائهم.تحميل الأصدقاء ينبغي أن يكون LAZY, ، أي.يتم تحميلها فقط عندما تحتاج إليها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top