2010-08-13 77 views
7

我已經創建了兩個使用Hibernate作爲具有ManyToMany關係的提供程序的JPA實體(Client,InstrumentTraded)。讓Hibernate爲MySQL生成表之後,似乎ManyToMany關係表不包含這兩個外鍵的主鍵。這允許多對多表中的重複記錄,這不是所需的結果。使用JPA與Hibernate提供程序的ManyToMany關係不會創建主鍵

表生成:

client(id,name) 
instrument_traded(id,name) 
client_instrument_traded(FK client_id, FK instrument_traded_id) 

優選表:

client_instrument_traded(PK,FK client_id, PK,FK instrument_traded_id) 

實體:

@Entity 
public class Client extends AbstractEntity<Integer> { 

    private static final long serialVersionUID = 1L; 

    @Basic(optional = false) 
    @Column(nullable = false, length = 125) 
    private String name; 

    @ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(joinColumns = { 
     @JoinColumn}, inverseJoinColumns = { 
     @JoinColumn(name = "instrument_traded_id")}, uniqueConstraints = 
    @UniqueConstraint(name = "UK_client_instruments_traded_client_id_instrument_traded_id", 
    columnNames = {"client_id", "instrument_traded_id"})) 
    @ForeignKey(name = "FK_client_instruments_traded_client_id", 
    inverseName = "FK_client_instruments_traded_instrument_traded_id") 
    private List<InstrumentTraded> instrumentsTraded; 

    public Client() { 
    } 

    public List<InstrumentTraded> getInstrumentsTraded() { 
     return instrumentsTraded; 
    } 

    public void setInstrumentsTraded(List<InstrumentTraded> instrumentsTraded) { 
     this.instrumentsTraded = instrumentsTraded; 
    } 

    ... 
} 



@Entity 
@Table(uniqueConstraints = { 
    @UniqueConstraint(name = "UK_instrument_traded_name", columnNames = {"name"})}) 
public class InstrumentTraded extends AbstractEntity<Integer> { 

    private static final long serialVersionUID = 1L; 

    @Basic(optional = false) 
    @Column(nullable = false, length = 50) 
    private String name; 

    @ManyToMany(mappedBy = "instrumentsTraded", fetch = FetchType.LAZY) 
    private List<Client> clients; 

    public InstrumentTraded() { 
    } 

    public List<Client> getClients() { 
     return clients; 
    } 

    public void setClients(List<Client> clients) { 
     this.clients = clients; 
    } 

    ... 

} 

做一些後研究它看起來像唯一的解決方案是mapping a join table with additional columns使用@OneToMany@IdClass和複合主鍵類,當我不需要額外的列。除了上面代碼中包含的解決方案之外,這是唯一的解決方案,它使用@UniqueConstraint以及@ManyToMany映射中的兩個外鍵列?對於像這樣的常見場景所需的工作量似乎有點荒謬。謝謝!

+0

http://stackoverflow.com/questions/1212058/how-to-make-a-composite-primary-key-java-persistence-annotation/6344626#6344626 – steveeen 2011-06-14 14:14:39

+0

還值得檢查,如果你意外地沒有添加一個記錄兩次,這發生在我身上,所以'list.add(x); list.add(x);'結果在列表中重複。 – CsBalazsHungary 2014-10-30 15:58:57

回答

2

您的映射看起來很奇怪(特別是@JoinTable批註的joinColumn部分)。我希望這樣的事情:

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(
    joinColumns= 
     @JoinColumn(name="CLIENT_ID", referencedColumnName="ID"), 
    inverseJoinColumns= 
     @JoinColumn(name="instrument_traded_id", referencedColumnName="ID"), 
    uniqueConstraints= 
     @UniqueConstraint(
      name="UK_client_instruments_traded_client_id_instrument_traded_id", 
      columnNames = {"client_id", "instrument_traded_id"} 
     ) 
) 
@ForeignKey(name = "FK_client_instruments_traded_client_id", 
inverseName = "FK_client_instruments_traded_instrument_traded_id") 
private List<InstrumentTraded> instrumentsTraded; 

但是,除非你想覆蓋缺省值(和我猜你這樣做),我只想跳過@JoinTable

+0

我想重寫默認值,因爲它將instrument_traded_id(instruments_traded_id)複數化。我有一個自定義命名策略,如果「_id」不存在於外鍵的末尾,則會添加「_id」。我可以刪除joinColumns = @ JoinColumn。你有沒有一個ManyToMany的例子,在ManyToMany表中創建一個由兩個外鍵組成的主鍵? – dukethrash 2010-08-13 14:00:43

+0

@dukethrash:'您是否有一個ManyToMany的示例,在ManyToMany表中創建一個由兩個外鍵組成的主鍵?'如果正確註釋,這是默認行爲。你有沒有'joinColumn'(或上面的那個)? – 2010-08-13 14:15:26

+0

是的我試過你(除了referencedColumn實際上是referencedColumnName),它仍然沒有生成主鍵。我甚至在InstrumentTraded上添加了以下內容,以查看是否會改變任何內容。 @ManyToMany(fetch = FetchType.LAZY,mappedBy =「instrumentsTraded」) private List clients; – dukethrash 2010-08-13 14:55:26

0

或者分裂您@ManyToMany到@OneToMany - @ManyToOne關係見here如何完成這個映射

6

下面就來解決這個問題的方法:

Client.java:

@ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL) 
@JoinTable(
     joinColumns = {@JoinColumn(name = "client_id")}, 
     inverseJoinColumns = {@JoinColumn(name = "instrument_traded_id")}, 
     uniqueConstraints = {@UniqueConstraint(
      columnNames = {"client_id", "instrument_traded_id"})} 
) 
private List<InstrumentTraded> instrumentsTraded; 

這是用於單向映射。如果您想要雙向關係,請將InstrumentTraded.class中的映射更改爲相同。

15

我有類似的問題。我所做的只是我從名單改變了集合類型設置:

private List<InstrumentTraded> instrumentsTraded; 

private Set<InstrumentTraded> instrumentsTraded; 

不知怎麼現在的Hibernate生成的連接表的主鍵。

+0

「所有偉大的事情都很簡單...」 – 2013-02-23 08:28:36

+0

是嗎?還是僅僅是Java集在內存中進行工作? – ViniciusPires 2014-08-02 19:26:02

+0

另外值得檢查一下,如果你意外沒有兩次添加記錄,這發生在我身上,所以'list.add(x); list.add(x);'結果在列表中重複。 – CsBalazsHungary 2014-10-30 15:57:26

相關問題