Я создал две сущности JPA (Client, InstrumentTraded), используя Hibernate в качестве провайдера, имеющего отношение ManyToMany. После того, как Hibernate сгенерировал таблицы для MySQL, оказалось, что таблица отношений 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 {
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 instrumentsTraded;
public Client() {
}
public List getInstrumentsTraded() {
return instrumentsTraded;
}
public void setInstrumentsTraded(List instrumentsTraded) {
this.instrumentsTraded = instrumentsTraded;
}
...
}
@Entity
@Table(uniqueConstraints = {
@UniqueConstraint(name = "UK_instrument_traded_name", columnNames = {"name"})})
public class InstrumentTraded extends AbstractEntity {
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 clients;
public InstrumentTraded() {
}
public List getClients() {
return clients;
}
public void setClients(List clients) {
this.clients = clients;
}
...
}
После некоторого исследования кажется, что единственное решение - сопоставить таблицу соединений с дополнительными столбцами , используя @OneToMany
@IdClass
и класс составного первичного ключа, когда мне не нужно дополнительные столбцы. Является ли это единственным решением, кроме того, которое я включил в приведенный выше код, который использует @UniqueConstraint
с двумя столбцами внешнего ключа в отображении @ManyToMany
? Кажется немного нелепым объем работы, необходимый для такого сценария, как этот. Спасибо!
Или Разделите @ManyToMany на отношения @OneToMany - @ManyToOne. См. здесь , как выполнить это сопоставление
Ваше сопоставление выглядит странно (в частности, часть joinColumn
аннотации @JoinTable
). Я ожидал чего-то вроде этого:
@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
.