Question

J'ai la classe suivante

public class ElementBean {
 private String link;
 private Set<ElementBean> connections;
}

Je dois créer une table de carte où les éléments sont mis en correspondance les uns aux autres dans un grand nombre à plusieurs rapports symétriques.

@ManyToMany(targetEntity=ElementBean.class)
@JoinTable(
    name="element_elements",
    joinColumns=@JoinColumn(name="FROM_ELEMENT_ID", nullable=false),
    inverseJoinColumns=@JoinColumn(name="TO_ELEMENT_ID", nullable=false)
)
public Set<ElementBean> getConnections() {
    return connections;
}

Je les exigences suivantes

Lorsque l'élément A est ajouté en tant que connexion à l'élément B, puis l'élément B doit devenir une connexion de l'élément A. Donc A.getConnections () devrait renvoyer B et B.getConnections () devrait retourner A. Je ne veux pas créer explicitement un 2 fiches pour la cartographie A à B et un autre pour B à A.

Est-ce possible?

Mise à jour: Merci pour toutes les suggestions
. Lorsque je tente @ suggestion deux dossiers de Pascal sont créés comme suit lorsque je tente de se connecter élément 1 avec l'élément 2.

FROM_ELEMENT_ID, TO_ELEMENT_ID
1, 2
2, 1

Je veux que les enregistrements soient symétriques où 1,2 est le même que 2,1

Comment cette question traitée?

Mise à jour Je explicitement créé un haricot carte

class ConnectionBean {
    ElementBean from;
    ElementBean to;
}

@NotNull
@ManyToOne
@JoinColumn(name="FROM_ELEMENT_ID", nullable=false)
public ElementBean getFrom() {
    return from;
}

@NotNull
@ManyToOne
@JoinColumn(name="TO_ELEMENT_ID", nullable=false)
public ElementBean getTo() {
    return to;
}

Je mis à jour le ElementBean à

public class ElementBean {
    private String link;
    private Set<ConnectionBean> from;
    private Set<ConnectionBean> to;
}

@OneToMany(mappedBy="from", fetch=FetchType.LAZY)
public Set<ConnectionBean> getFrom() {
    return from;
}

@OneToMany(mappedBy="to", fetch=FetchType.LAZY)
public Set<ConnectionBean> getTo() {
    return to;
}

Ici, je peux contrôler l'insertion et la suppression. Par exemple avant d'insérer un nouveau ConnectionBean, je vérifie si une connexion existe entre les éléments A & B en cochant la table de connexion pour les enregistrements où
    ((De == A && à == B) || (de == B && à == A))
avant l'insertion.

Était-ce utile?

La solution

Lorsque vous travaillez avec plusieurs à plusieurs, vous n'avez pas à vous soucier trop de double emploi comme Hibernate se chargera pour vous. Vous ne devez vous soucier de faire aider que votre modèle d'objet est cohérent et Hibernate ne sera pas nécessairement avec cela.

Dans la méthode addConnection() vous ne devriez pas avoir une méthode de getConnections() qui retourne la connexion réelle, revenir plutôt une version en lecture seule, vous devez vous assurer que vous gérer les deux côtés de la relation:

addConnection(ElementBean element) {
    if (element ==null) { 
        throw new IllegalArgumentException("cannot add null element"); 
    }
    connections.add(element);
    element.getConnections0().add(this);
}

Cela signifie que votre exigence tenir et quand il l'enregistre sauvera bien. Il ne sauvera pas deux fois plus qu'il remarquerez que l'un est une référence en arrière pour l'autre. Vous devriez probablement faire le paquet privé ou getConnections0().

Autres conseils

Ce sera résolu par la première cache de niveau de mise en veille prolongée de garder une trace des références aussi longtemps que vous associez le m-2 m des deux côtés.

Lorsque vous travaillez avec des liens bi-directionnel, vous devez prendre en charge le lien des deux côtés et, citant la documentation:

De nombreux développeurs de programme de défense et de créer un mode de gestion de lien pour définir correctement les deux côtés.

Dans votre cas, je vous suggère d'ajouter les méthodes suivantes:

public Set<ElementBean> getConnections() {
    return connections;
}

public void setConnections(Set<ElementBean> connections) {
    this.connections = connections;
}

public void addToConnection(ElementBean connection) {
    this.getConnections().add(connection);
    connection.getConnections().add(this);
}

public void removeFromConnection(ElementBean connection) {
    this.getConnections().remove(connection);
    connection.getConnections().remove(this);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top