JPA 多对多,带有额外的列

2022-09-04 21:46:36

我有以下问题需要解决。核心问题是我想在JPA中的许多多关系的JoinTable中添加额外的列。在我的情况下,我有以下实体。

主题是一个简单的实体,它有许多远程文档(一个远程文档可能被许多主题引用,因此它应该是ManyToMany关系)。此外,RemoteDocument 实体是只读的,因为它只能从 Oracle 实例化视图中读取,此外,禁止对此实例化视图进行任何更改。因此,我想存储与某些主题相关的远程文档的顺序。事实上,我可以用其他实体做类似的事情:

@Entity
public class Topic {
 @Id
 private Long id;
 @Basic
 private String name;

    @OneToMany
 private Set<TopicToRemoteDocument> association;
}

@Entity
public class RemoteDocument {
 @Id
 private Long id;
 @Basic
 private String description;
}

@Entity
public class TopicToRemoteDocument {
 @OneToOne
 private Topic topic;
 @OneToOne
 private RemoteDocument remoteDocument;
 @Basic
 private Integer order;
}

在这种情况下,额外的实体 TopicToRemoteDocument 帮助我用 OneToMany 替换 ManyToMany 关联,并添加额外的字段顺序。

但是我想有 ManyToMany 关系,但在连接表中配置了额外的列


答案 1

使用列表而不是设置,与注释一起,JPA将自动处理顺序:@OrderColumn

@MappedSuperclass
public class BaseEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    public Long getId(){
        return id;
    }

    public void setId(final Long id){
        this.id = id;
    }

}

@Entity
public class Topic extends BaseEntity{

    @ManyToMany(mappedBy = "topics")
    @OrderColumn
    private List<Document> documents = new ArrayList<Document>();

    public List<Document> getDocuments(){
        return documents;
    }

    public void setDocuments(final List<Document> documents){
        this.documents = documents;
    }

}

@Entity
public class Document extends BaseEntity{

    @ManyToMany
    @OrderColumn
    private List<Topic> topics = new ArrayList<Topic>();

    public List<Topic> getTopics(){
        return topics;
    }

    public void setTopics(final List<Topic> topics){
        this.topics = topics;
    }

}

生成的 DDL(使用休眠和 HSQL):

create table Document (
    id bigint generated by default as identity (start with 1),
    primary key (id)
);

create table Document_Topic (
    documents_id bigint not null,
    topics_id bigint not null,
    topics_ORDER integer not null,
    documents_ORDER integer not null,
    primary key (documents_id, topics_ORDER)
);

create table Topic (
    id bigint generated by default as identity (start with 1),
    primary key (id)
);

alter table Document_Topic 
    add constraint FK343B5D0B481100B2 
    foreign key (documents_id) 
    references Document;

alter table Document_Topic 
    add constraint FK343B5D0B558627D0 
    foreign key (topics_id) 
    references Topic;

答案 2

我会尽量避免使用 a,除非你允许重复。List

有一个注释会自动执行此操作。你试过吗?@OrderColumn

@Entity
public class Topic {
 @Id
 private Long id;
 @Basic
 private String name;

 @OneToMany
 @OrderColumn
 private Set<TopicToRemoteDocument> association;
}

推荐