2010-10-28 56 views
13

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

该主题是一个简单的实体,它有很多RemoteDocument(一个RemoteDocument可能被许多Topic引用,因此它应该是ManyToMany关系)。 RemoteDocument实体也是只读的,因为它可能只能从Oracle物化视图中读取,而且任何改变这个物化视图都是禁止的。所以我想存储与某个Topic有关的RemoteDocuments的顺序。事实上,我可以做这样的事情有更多的实体:

@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帮助我一对多更换多对多的关联,并添加额外的字段顺序。

但我希望有多对多的关系,但与配置附加列与@OrderColumn注释中加入表

+0

什么是您的JPA提供程序? JPA 1.0没有标准化的注释,但是你的JPA提供者可能有一个扩展。 – 2010-10-28 16:19:11

回答

10

使用列表,而不是一组,一起和JPA将自动执行的命令的护理:

@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; 
+0

感谢您的回答,它实际上是我需要的,除了我使用的是JPA 1.0而不是JPA 2.0 ...所以看起来我需要迁移到JPA 2.0 – endryha 2010-10-28 14:42:31

+4

a)如果它是正确的答案,您应该接受它b)我不认为在我的答案中有关于JPA 2的任何具体内容。还应该使用JPA 1。哦,OrderColumn是JPA 2,不知道。 – 2010-10-28 14:46:17

2

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

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

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

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

一种技术,该技术是在创建许多一对多映射类实体时有用是属性的ID在类与@ManyToOne指定这使得这种类充当复合键类沿着:

@Entity 
@Table(name = "market_vendor") 
public class MarketVendor implements Serializable 
{ 
    @Id 
    @ManyToOne 
    @JoinColumn(name = "market_id") 
    private Market market; 

    @Id 
    @ManyToOne 
    @JoinColumn(name = "vendor_id") 
    private Vendor vendor; 

    @Basic 
    @Column(name="active") 
    private boolean active; 

    public MarketVendor(Market market, Vendor vendor, boolean active) 
    { 
    this.market = market; 
    this.vendor = vendor; 
    this.active = active; 
    } 
} 

这使您可以在同一个类中定义组合主键,而不必拥有单独的主键类。您还需要使该类可序列化。