2012-04-06 184 views
5

我有两个实体类'用户'和'文档'。每个用户都有一个收件箱和一个发件箱,实际上它们是两个列表,每个文档可以驻留在多个收件箱和发件箱的用户中。这里是我的课:JPA:两个实体之间有多个多对多的关系?

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

} 

当我运行PROGRAMM并尝试将文档分配给用户的收件箱(反之亦然),我收到以下错误:

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 (?, ?)") 

生成的关联表看起来像这样:

DOCUMENT_USER 
useroutbox_ID | outbox_ID |userinbox_ID | inbox_ID 

我该如何为这种多对多关系分配默认值?制作两个关联表是否会更好 - >一个用于收件箱关系,另一个用于发件箱关系?我将如何实现这一目标?解决这个问题的其他方法?

任何帮助高度赞赏 - 非常感谢提前!

+0

尝试将@ManyToMany(cascade = CascadeType.ALL)放在其getter方法而不是其字段上。 – 2012-04-06 12:44:38

+0

@tech_learner在域中添加注释是没问题的,这不是问题。 – 2012-04-06 12:49:05

回答

12

我认为更好的选择是有两个单独的表,每个关系一个。因为你实际上在两个不同的实体之间有两个关系,而不是一个与四个不同实体的关系。

因此,您应该为Document一侧的每个属性添加@JoinTable注释,因为这些关系的User一侧被映射到属性。类似以下内容:

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

} 

将其他实体保留为现在的状态。希望这可以帮助。

+0

太棒了!非常感谢您的快速和有用的答案 - 现在它就像一个魅力:-) – salocinx 2012-04-06 13:02:40

相关问题