2016-08-26 4 views
1

Ich bin ORM sehr neu und kann jedem eine Idee vorschlagen, das folgende Szenario zu übertreffen.Objektrelationales Mapping

Ich habe eine Chat-Klasse als Gebrüll

@Entity 
public class Chat {  

    @Id 
    @GeneratedValue 
    @Column(name="Id") 
    private int id; 

    @ManyToOne 
    private User userSent; 

    @ManyToOne 
    private User userRecieve; 

    private Date time; 

    @Column(name="message", length=50) 
    private String message; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 
    public Date getTime() { 
     return time; 
    } 

    public void setTime(Date time) { 
     this.time = time; 
    } 

    public String getMessage() { 
     return message; 
    } 

    public void setMessage(String message) { 
     this.message = message; 
    } 
} 

Und die User-Klasse als Gebrüll

@Entity 
public class User { 

    @Id 
    @GeneratedValue 
    private Integer id; 

    private String name; 

    private String email; 

    private String password; 


    @OneToMany 
    private List<Chat> chats; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 
    public List<Chat> getChats() { 
     return chats; 
    } 

    public void setChats(List<Chat> chats) { 
     this.chats = chats; 
    } 
} 

Und mein Problem ist ein Benutzer viele Chats und der Chat hat zwei verschiedene Arten von Benutzern hat als Empfänger und Absender, aber beide gehören zu einem bestimmten Chat.

Und meine Frage ist, wie ich es erklären kann, wie man die Beziehung gibt. Vielen Dank im Voraus

+0

Die Chats-Liste des Benutzers enthält also alle Chats, in denen der Benutzer entweder ein Sender oder ein Empfänger ist? –

+0

Bidirektionale Eins-zu-Viele-Verknüpfungen werden im Handbuch behandelt: http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#associations-one-to-many-bidirektional –

+0

Aber das ist eher eine "zwei zu viele" Beziehung. Es ist sehr kompliziert, das bidirektional zu machen. Ich würde es unidirektional machen und eine "findByUser" - oder "findByUserId" -Methode in Ihrem 'ChatRepository' bereitstellen. –

Antwort

0

Es ist nicht möglich eine bidirektionale zwei bis viele Beziehung (wo beide dieser zwei sind verschiedene Felder) mit JPA auf einfache Art und Weise auszudrücken.

Die einfachste Möglichkeit, dies zu lösen, besteht darin, die Beziehung unidirektional zu machen, indem das Feld chats von User entfernt wird. Dann in Ihrem Repository/DAO für Chat bieten Sie eine Funktion findByUser mit einer Abfrage wie

SELECT Chat c WHERE c.userSent = :user OR c.userReceive = :user 

diese Weise können Sie immer noch die Sammlung von Chats für einen bestimmten Benutzer bekommen, nur nicht durch die User Unternehmen selbst.


würde Eine andere Lösung ist die Beziehung viele zu viele zu machen und eine Eigenschaft der Beziehung hinzufügen, dass die Art der Teilnahme an dem Chat des Benutzers anzeigt. Sie müssten eine Zwischeninstanz wie

@Entity 
public class ChatParticipation { 
    public static enum Type { 
    SENDER, 
    RECEIVER 
    } 

    private Chat chat; 
    private User user; 
    private Type type; 
} 

und ändern Sie die anderen Einheiten Getter

@Entity 
public class Chat { 
    @OneToMany 
    private Set<ChatParticipation> participations; 

    public User getSender() { 
    return participations.stream() 
     .filter(p -> p.getType() == ChatParticipation.Type.SENDER) 
     .map(ChatParticipation::getUser) 
     .findFirst().get(); 
    } 

    public User getReceiver() { 
    return participations.stream() 
     .filter(p -> p.getType() == ChatParticipation.Type.RECEIVER) 
     .map(ChatParticipation::getUser) 
     .findFirst().get(); 
    } 
} 

@Entity 
public class User { 
    @OneToMany 
    private Set<ChatParticipation> participations; 

    public Set<Chat> getChats() { 
    return participations.stream() 
     .map(ChatParticipation::getChat) 
     .collect(Collectors.toSet()); 
    } 
} 

Sie sollten wahrscheinlich Cache die Getter Ergebnisse erstellen. Außerdem müssen Sie eine Lösung für die Setter finden.