2012-04-06 11 views
5

Mam dwie klasy encji "Użytkownik" i "Dokument". Każdy użytkownik ma skrzynkę odbiorczą i skrzynkę nadawczą, które w rzeczywistości są dwiema listami, a każdy dokument może znajdować się w wielu skrzynkach odbiorczych i skrzynkach nadawczych użytkowników. Oto moje zajęcia:JPA: Wiele relacji wiele do wielu między dwoma podmiotami?

@Entity 
public class User { 

    @Id 
    private Long id; 

    @ManyToMany(mappedBy = "userinbox", cascade=CascadeType.ALL) 
    private List<Document> inbox = new ArrayList<Document>(); 
    @ManyToMany(mappedBy = "useroutbox", cascade=CascadeType.ALL) 
    private List<Document> outbox = new ArrayList<Document>(); 

} 

@Entity 
public class Document { 

    @Id 
    private Long id; 

    @ManyToMany(cascade=CascadeType.ALL) 
    private List<User> userinbox = new ArrayList<User>(); 
    @ManyToMany(cascade=CascadeType.ALL) 
    private List<User> useroutbox = new ArrayList<User>(); 

} 

Gdy uruchamiam programm i spróbować przypisać dokument do skrzynki odbiorczej użytkownika (i vice versa), pojawia się następujący błąd:

Error Code: 1364 

Call: INSERT INTO DOCUMENT_USER (userinbox_ID, inbox_ID) VALUES (?, ?) 
    bind => [2 parameters bound] 

Internal Exception: java.sql.SQLException: Field 'useroutbox_ID' doesn't have a default value 

Query: DataModifyQuery(name="userinbox" sql="INSERT INTO DOCUMENT_USER (userinbox_ID, inbox_ID) VALUES (?, ?)") 

Wygenerowany stowarzyszenie tabela wygląda następująco:

DOCUMENT_USER 
useroutbox_ID | outbox_ID |userinbox_ID | inbox_ID 

Jak przypisać wartości domyślne dla relacji między wieloma a wieloma? Czy lepiej byłoby utworzyć dwie tabele powiązań -> jedną dla relacji skrzynki odbiorczej, inną dla relacji nadawczej? Jak to osiągnąć? Inne rozwiązania tego problemu?

Każda pomoc bardzo ceniona - wielkie dzięki z góry!

+0

spróbuj umieścić @ManyToMany (cascade = CascadeType.ALL) na swojej metodzie gettera, a nie na jego polu. –

+0

@tech_learner umieszczanie adnotacji na polach jest w porządku, to nie problem. –

Odpowiedz

12

Myślę, że lepszym rozwiązaniem jest posiadanie dwóch oddzielnych tabel, po jednej na relację. Ponieważ faktycznie masz dwie relacje między dwiema różnymi jednostkami, a nie jedną relację z czterema różnymi jednostkami.

Należy dodać adnotację @JoinTable do każdego z atrybutów po stronie Document od czasu, gdy relacje te są odwzorowane na właściwość. Coś jak poniżej:

@Entity 
public class Document { 

    @Id 
    private Long id; 

    @ManyToMany(cascade=CascadeType.ALL) 
    @JoinTable(name = "document_inbox", joinColumns = @JoinColumn(name = "userinbox_id"), 
       inverseJoinColumns = @JoinColumn(name = "inbox_id")) 
    private List<User> userinbox = new ArrayList<User>(); 
    @ManyToMany(cascade=CascadeType.ALL) 
    @JoinTable(name = "document_outbox", joinColumns = @JoinColumn(name = "useroutbox_id"), 
       inverseJoinColumns = @JoinColumn(name = "outbox_id")) 
    private List<User> useroutbox = new ArrayList<User>(); 

} 

Pozostaw drugi element taki, jaki jest teraz. Mam nadzieję że to pomoże.

+0

Świetnie! Wielkie dzięki za szybką i przydatną odpowiedź - teraz działa jak urok :-) – salocinx