Ho creato due entità JPA (Client, InstrumentTraded) utilizzando Hibernate come provider con una relazione ManyToMany. Dopo aver lasciato che Hibernate generi le tabelle per MySQL, sembra che la tabella delle relazioni ManyToMany non contenga chiavi primarie per le due chiavi esterne. Ciò consente di duplicare i record nella tabella many-to-many, che non è il risultato desiderato.ManyToMany relationship using JPA with Hibernate provider non crea chiavi primarie
tabelle generate:
client(id,name)
instrument_traded(id,name)
client_instrument_traded(FK client_id, FK instrument_traded_id)
tavolo preferita:
client_instrument_traded(PK,FK client_id, PK,FK instrument_traded_id)
Entità:
@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;
}
...
}
Dopo aver fatto alcune ricerca sembra l'unica soluzione è per mapping a join table with additional columns utilizzando @OneToMany
@IdClass
e una classe di chiave primaria composita quando non ho bisogno di colonne aggiuntive. È questa l'unica soluzione oltre a quella che ho incluso nel codice sopra, che utilizza un @UniqueConstraint
con le due colonne chiave esterna nella mappatura @ManyToMany
? Sembra un po 'ridicola la quantità di lavoro necessaria per uno scenario comune come questo. Grazie!
http://stackoverflow.com/questions/1212058/how-to-make-a-composite-primary-key-java-persistence-annotation/6344626#6344626 – steveeen
Vale anche la pena di verificare se non è stato accidentalmente aggiunto un record due volte, questo è successo a me, quindi 'list.add (x); list.add (x); 'risultati duplicati negli elenchi. – CsBalazsHungary