2011-12-19 12 views
5

Diciamo che abbiamo la classe entità utente. L'utente può essere amico di altri utenti. Come posso mappare questo campo di raccolta di riferimento automatico senza creare una nuova entità chiamata Connessione o creando più voci nel database?mappatura del campo autoreferenziale in JPA

@Entity 
public class User { 
... 
@ManyToMany 
private Collection<User> friends; 
... 
} 

USER_ID-FRIEND_ID 
1 - 2 
2 - 1 (duplicate... I don't need it) 
+0

Una relazione molti-a-molti autoreferenziale è valida e può essere mappata utilizzando le annotazioni JPA. Come tutte le relazioni molti-a-molti, è necessario definire una tabella bridge per memorizzare entrambi i lati della relazione. L'entità definirà un campo per il lato proprietario e un altro campo per il lato mappato della relazione. – scottb

risposta

1

Non è possibile - è necessario entrambi i record nel database.

In realtà, per le relazioni di amicizia, direi che un database grafico come neo4j è la cosa giusta da usare. Lì hai i due utenti e aggiungi semplicemente un bordo "amici".

+0

interessante ... ho pensato che ci potrebbe essere un trucco o stam –

+2

Questa risposta non è corretta. Una relazione molti-a-molti autoreferenziale è valida e può essere mappata in JPA senza definire nuove entità.La relazione richiede una tabella di bridge, come fanno tutte le relazioni molti-a-molti. – scottb

6

seguito è un'istantanea dal mio codice per ElementEntity:

@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY) 
private List<ElementEntity> children; 

@JoinColumn(name = "ParentId", referencedColumnName = "ElementId") 
@ManyToOne(fetch = FetchType.LAZY) 
private ElementEntity parent; 

Dove sulla banca dati ci sono campi:

  • ElementId - chiave primaria;
  • ParentId relazione con i genitori
+0

grazie amico per il tuo tempo. non sto cercando una relazione genitore-figlio. –

+3

@HayatiGuvence cosa c'è che non va - basta rinominare ParentId in USER_ID e elementId in friend_Id – Dewfy

1

Almeno avrete bisogno di una relational table.

in modo da avere un tavolo USER e un FRIENDS:

user_id friend_id 
    1  2 

Ma @Bozho risposta è il modo migliore di miniera (neo4j).

+0

:) non si può avere lo stesso nome di colonna in una tabella –

+0

grazie! solo un typ0 – ssedano

0

Beh, in effetti è possibile.

È possibile utilizzare annotazioni come @PreUpdate, @PrePersists, @PostUpdate e così convertire manualmente gli elementi di una raccolta. In questo modo la tua entità può eseguire il rendering nel modo desiderato, mentre nel database si memorizza solo un testo non elaborato.

Un'alternativa più plausibile sarà l'uso dell'annotazione @Convert, disponibile da jpa 2.1 (@UserType in hibernate). Indica a jpa di convertire il campo in un altro tipo ogni volta che legge/salva nel database. Per questo dovresti usare @Convert anotation, specificando e AttributeConverter oggetto.

Per esempio

public class Parent { 
     @Id 
     private Integer id; 

     @Convert(converter = FriendConverter.class) 
     private Set<Parent>friends; 
    } 

E classe convertitore simile al seguente:

@Component 
    public class FriendConverter implements AttributeConverter<List, String>{ 
     @Autowired 
     private SomeRepository someRepository; 

     @Override 
     public String convertToDatabaseColumn(List attribute) { 
     StringBuilder sb = new StringBuilder(); 
     for (Object object : attribute) { 
      Parent parent = (parent) object; 
      sb.append(parent.getId()).append("."); 
     } 
     return sb.toString(); 
     } 

     @Override 
     public List convertToEntityAttribute(String dbData) { 
     String[] split = dbData.split("."); 
     List<Parent>friends = new ArrayList<>(); 
     for (String string : split) { 
      Parent parent = someRepository.findById(Integer.valueOf(string)); 
      friends.add(accion); 
     } 
     return friends; 
     } 
    } 

Si tratta di un'implementazione fittizia ma ti dà l'idea.

Come commento personale, consiglio di mappare la relazione come dovrebbe. In futuro ti eviterà problemi. AttributeConverter è utile quando si lavora con le enumerazioni

Problemi correlati