Domanda

Sto cercando di progettare un qualche tipo di relazione utente-utente, ad esempio "l'utente A segue l'utente B" e "L'utente A vuole essere amico dell'utente B".

Ho una classe User e il modo in cui è progettata è simile a questa:

@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;

}

Sto riscontrando due problemi:

  • Hibernate mi sta dando il problema impossibile recuperare più bagagli contemporaneamente
  • Ho cercato online, la gente diceva di rimuovere FetchType.EAGER o di cambiarlo in Imposta invece di Elenco, ma il risultato è stato Il campo non ha un valore predefinito

Ho la sensazione che la relazione non sia definita correttamente e inoltre dovrei vedere più tabelle, perché in questo momento vedo solo la tabella Utente e la tabella Utente_Utente.


Aggiorna

Quanto segue crea 3 tabelle, amici, follower e richiedenti. È in qualche modo ottimizzato rispetto a 5 tabelle? E c'è qualche vantaggio in questo rispetto a quanto suggerito dal signor 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;
È stato utile?

Soluzione

Prima di tutto, per implementare la tua funzione, dovresti usare @ManyToMany invece di @OneToMany.Dovrebbe assomigliare a questo:

@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;
}

Le tue relazioni mi sembrano bidirezionali.Se utilizzi @OneToMany, significa che C has 2 followers A and B= A and B only follows C.Tuttavia, il fatto è che una persona può seguire molte persone e una persona può essere seguita da molte persone.In altre parole, A and B can also follow D.

Inoltre, non dovresti assolutamente usare cascadeType.ALL.Questa politica a cascata significa che se un utente elimina il suo account e tu elimini la voce corrispondente nel database, anche tutti i suoi amici, ecc.

Altri suggerimenti

Hibernate genererà solo una tabella per l'entità Utente e presumo una tabella di riferimento incrociato per la relazione Utente-Utente.Una soluzione alternativa per avere tabelle diverse potrebbe essere l'impostazione di entità diverse per le diverse relazioni, ad esempio

Entità utente

@OneToMany
List<Follower> followers;

Entità follower

@Entity
class Follower
...
@ManyToOne
User user;

@Id
@Generated
int id;

Per quanto riguarda il recupero EAGER, potresti effettivamente volere che tutti siano PIGRO, poiché a seconda di come è impostato il tuo database, tutti quei caricamenti desiderosi potrebbero essere piuttosto costosi.Solo quando l'utente vuole caricare gli utenti follower, vorrei recuperarli.

Separare User da Friends e provare a creare una tabella con almeno 2 colonne che associ il User_ID a tutto il suo Friends_IDs che è fondamentalmente un riferimento a User_ID

Inoltre, EAGER caricherà TUTTI i dati non appena lo chiami per la prima volta.Significa che caricherà tutti gli utenti e i loro amici.Il caricamento degli amici dovrebbe essere LAZY, ovvero caricato solo quando ne hai bisogno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top