ไฮเบอร์เนต: การทำแผนที่ความสัมพันธ์ระหว่างผู้ใช้กับเพื่อนในเครือข่ายโซเชียล

เป็นเวลาพอสมควรแล้วที่ฉันพยายามเข้าใจปัญหานี้ และจากการค้นหาใน Google หลายๆ คนก็ประสบปัญหาคล้ายกัน

ฉันกำลังพยายามสร้างโมเดลผู้ใช้ในโซเชียลเน็ตเวิร์กโดยใช้ไฮเบอร์เนต และอะไรคือพื้นฐานสำหรับโซเชียลเน็ตเวิร์กมากกว่าการสร้างแผนที่ความสัมพันธ์ฉันมิตร ผู้ใช้ทุกคนในระบบควรมีรายชื่อเพื่อน และฉันคิดว่านี่อาจเป็นงานที่ง่ายมาก (แค่ใช้ความสัมพันธ์แบบ ManyToMany ใช่ไหม?) ดังนั้นฉันจึงลองทำสิ่งต่อไปนี้:

@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   protected List<User> friends = null
}

ปัญหาตอนนี้คือมันบอกฉันว่าฉันใช้ ManyToMany ผิดโดยไม่มีความแตกต่างที่ชัดเจนระหว่างเพื่อนกับเพื่อน จนถึงตอนนี้ดีมาก ฉันได้รับข้อผิดพลาด แต่ฉันจะทำสิ่งที่ฉันต้องการได้อย่างไร

มีความคิดอะไรบ้าง? ฉันถึงจุดสิ้นสุดของภูมิปัญญาของฉัน


person cdecker    schedule 28.12.2008    source แหล่งที่มา


คำตอบ (5)


ข้อเท็จจริงเกี่ยวกับหลายต่อมากคือจำเป็นต้องมีการกำหนดค่าเพิ่มเติมอีกเล็กน้อย เนื่องจากจำเป็นอย่างยิ่งที่ Hibernate จะสร้างตารางความสัมพันธ์ ลองสิ่งนี้:


@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   @JoinTable(name = "user_friends", 
       joinColumns = @JoinColumn(name = "user_id"), 
       inverseJoinColumns = @JoinColumn(name = "friend_id"))
   protected List friends = null;
   @ManyToMany(mappedBy = "friends")
   protected List befriended = null;
}

หวังว่ามันจะได้ผล =)

แก้ไข: นอกจากนี้ ควรระมัดระวังอย่างมากกับประเภทการดึงข้อมูล... คุณสามารถป้อนผู้ใช้ที่ดึงข้อมูลลูปที่ไม่อยู่ในการควบคุมและรับ DB ทั้งหมด

person Juan Manuel    schedule 29.12.2008
comment
ฉันสามารถสร้างรายชื่อกับเพื่อนได้เพียงรายชื่อเดียวเท่านั้น จะเป็นเพื่อนและเป็นเพื่อนได้ที่ไหน? จะต้องลิสต์ในชั้นเรียนไปเพื่ออะไร? - person dikkini; 03.07.2014

คำอธิบายประกอบ ManyToMany มีพารามิเตอร์ mappedBy ฉันเดาบางอย่างเช่น

@ManyToMany(mappedBy = "friends")

อาจทำงานได้ ไม่ว่าในกรณีใด โปรดดูเอกสาร .

แก้ไข:

ดูเหมือนว่าความสัมพันธ์แบบหลายต่อมากจำเป็นต้องเข้าถึงได้จากทั้งสองด้าน ขณะนี้คุณสามารถเข้าถึงได้จากปลายด้านเดียวเท่านั้น บางทีคุณควรเพิ่มความสัมพันธ์อื่นด้วย:

@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   protected List<User> friends = null;
   @ManyToMany(mappedBy = "friends")
   protected List<User> befriended = null;
}

หากไม่ได้ผล คุณสามารถแนะนำคลาสแยกต่างหากที่แสดงความสัมพันธ์ระหว่างผู้ใช้สองคนได้เสมอ และให้ผู้ใช้ทุกคนมีคอลเลกชันอินสแตนซ์ของคลาสนี้

person Ole    schedule 28.12.2008

จุดดีและอันที่จริงฉันก็ลองแล้ว ปัญหาคือฉันได้รับการร้องเรียนเกี่ยวกับแอตทริบิวต์ mappedBy ที่ถูกตั้งค่าไว้ทั้งสองด้านของความสัมพันธ์ ซึ่งเป็นเรื่องจริง แต่ไม่ถูกต้อง ฉันสงสัยว่า @ManyToMany แบบง่าย ๆ พร้อมด้วยแบบสอบถามแบบกำหนดเองที่ชาญฉลาดเพื่อดึงข้อมูลเพื่อนอาจเป็นวิธีแก้ปัญหา: ManyToMany จะสร้างตารางเข้าร่วมด้วย user_id และ friend_id, แต่แบบสอบถามจะตรงกับฟิลด์ใดฟิลด์หนึ่ง โดยส่งคืนผู้ใช้ทั้งหมดที่ตรงกับฟิลด์ใดฟิลด์หนึ่ง friend_id หรือ user_id นั่นคือ มีความคิดอะไรบ้าง?

person cdecker    schedule 28.12.2008

แน่นอนว่าจะเป็นการแก้ไขที่ดี แต่ฉันยังขายไม่หมด โดยพื้นฐานแล้วในการหาเพื่อน ฉันจะต้องรวมคอลเลกชันทั้งสองเข้าด้วยกัน ซึ่งค่อนข้างไม่น่าพอใจเลย

ไม่มีทางที่จะสร้างความสัมพันธ์แบบ idempotent และแบบสะท้อนกลับในจำศีลได้เลยหรือ?

person cdecker    schedule 28.12.2008

วันนี้ฉันก็มีปัญหาเดียวกันเช่นกัน

@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   protected List<User> friends = null
}

ควรจะโอเคฉันใช้โครงสร้างที่คล้ายกัน อย่างไรก็ตาม ฉันได้รับข้อยกเว้นในการโหลดแบบ Lazy Loading และเมื่อตั้งค่า fetchType เป็น EAGER ฉันได้รับการร้องเรียนเกี่ยวกับการกำหนดค่าเริ่มต้นของ Bag แบบเรียกซ้ำ

ฉันจะแก้ไขปัญหาได้อย่างไร: ในแบบสอบถามที่คุณใช้เพื่อดึงข้อมูล 'ผู้ใช้' ให้ดำเนินการดังนี้:

from User as u left join fetch u.friends

นี่จะเป็นการเริ่มต้นรายชื่อเพื่อนสำหรับเอนทิตีนั้น ได้รับการเตือนแม้ว่าจะไม่ได้เริ่มต้นเพื่อนจากเพื่อนเหล่านั้นก็ตาม นั่นเป็นสิ่งที่ดีจริงๆ

person Matthias van der Vlies    schedule 25.02.2009