2017-04-21 83 views
1

我的数据库包含3个表:persondocumentpeson_document。人员和文档具有多对多的关系,并与包含添加列的person_document表连接。 这是我的映射:映射@ManyToMany关联表与额外的列

class Person { 
    @Cascade(CascadeType.ALL) 
    @OneToMany(mappedBy = "compositePK.person", orphanRemoval = true) 
    Set<PersonDocument> personDocuments; 
} 

class Document { 
    @OneToMany(mappedBy = "compositePK.document") 
    Set<PersonDocument> personDocuments; 
} 

class PersonDocument { 

    @EmbeddedId 
    private CompositePK compositePK; 

    @Column(name = "person_origin_id") 
    private String personID; 

    @ManyToOne(fetch = FetchType.LAZY) 
    private Provider provider;  

    @Embeddable 
    public static class CompositePK implements Serializable { 

     @ManyToOne(fetch = FetchType.LAZY) 
     private Person person; 

     @ManyToOne(fetch = FetchType.LAZY) 
     @JoinColumn(name = "documents_guid") 
     private Document document; 
    } 

在我的代码我想保存此实体是这样的:

Set<PersonDocument> pds = new HashSet<>(); 
Document doc = new Document(); 
//set doc, set person to new PersonDocument and add once on pds set. 
person.getPersonDocuments().addAll(pds); 
personRepository.save(person); 

的问题是,Hibernate并不保存并抛出异常:insert or update on table violates foreign key constraint - 因为在document表中没有记录。那么为什么冬眠在保存person_document之前不坚持document以及如何解决这个问题?

回答

3

试试这个:

public class Person { 
    @OneToMany(mappedBy = "person", orphanRemoval = true, cascade= CascadeType.ALL) 
    Set<PersonDocument> personDocuments; 
} 


class Document { 
    @OneToMany(mappedBy = "document") 
    Set<PersonDocument> personDocuments; 
} 


public class PersonDocument { 

    @EmbeddedId 
    private CompositePK compositePK; 

    @MapsId("person") 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "person_origin_id") 
    private Person person; 

    @MapsId("document") 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "documents_guid") 
    private Document document; 

    @ManyToOne(fetch = FetchType.LAZY) 
    private Provider provider;  
} 


@Embeddable 
public class CompositePK implements Serializable { 

    //these fields should have the same type as the ID field of the corresponding entities 
    //assuming Long but you have ommitted the ID fields 

    private Long person; 

    private Long document; 

    //implement equals() and hashcode() as per the JPA spec 
} 


//you must always set both side of the relationship 
Person person = new Person(); 
Document document = new Document(); 
PersonDocument pd = new PersonDocument(); 
pd.setPerson(person); 
pd.setDocument(document); 
person.getPersonDocuments.add(pd);//assumes initialized 
+0

最多从我投票。就我个人而言,我总是用2'OneToMany'取代我的'ManyToMany'。它提供了更多的控制权,例如级联,并允许您通过更改人员文档上的引用将文档从一个人移动到另一个人。在我看来'ManyToMany'应该永远不会实现,它会导致比解决问题更多的问题。 –

+0

艾伦,谢谢你的回答,但现在我有另一个问题 - 当我试图保存'PersonDocument'我得到异常:'无法通过model.entity.PersonDocument $ CompositePK的反射设置器设置字段值。文件',不明白为什么是这样? –

+0

它是否在它自己的类定义文件中?您的原始代码将其作为PersonDocument中的嵌套类。正如JPA规范所指出的那样:“实体[和可嵌入]类必须是顶级类。” JPA规范章节2.1和2.5 –