Я хотел бы иметь в своей сущности составной первичный ключ, состоящий из 2 столбцов (атрибутов), и чтобы один из них был одновременно внешним ключом.
Я пишу что-то вроде этого, но не знаю, работает ли это, потому что внешний ключ помечен как сгенерированное значение в источнике данных IntelliJ
@Entity
@Table(name = "service_point")
@Access(AccessType.PROPERTY)
@IdClass(ServicePointId.class)
public class ServicePoint {
private Long providerId;
private Integer servicePointNumber;
private Provider provider;
@Id
@Basic(optional = false)
@Column(name = "provider_id", nullable = false, insertable = false,
updatable = false, columnDefinition = "BIGINT UNSIGNED")
public Long getProviderId() {
return providerId;
}
public void setProviderId(Long providerId) {
this.providerId = providerId;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "service_point_no", nullable = false, columnDefinition = "BIGINT UNSIGNED")
public Integer getServicePointNumber() {
return servicePointNumber;
}
public void setServicePointNumber(Integer servicePointNumber) {
this.servicePointNumber = servicePointNumber;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "provider_id")
public Provider getProvider() {
return provider;
}
public void setProvider(Provider provider) {
this.provider = provider;
}
}
ОБНОВЛЕНО:
Я протестировал Брайана Восбурга, и он работает:
transaction.begin();
em.persist(provider);
ServicePoint servicePoint = new ServicePoint(provider, 1);
em.persist(servicePoint);
transaction.commit();
ServicePoint servicePoint2 = em.find(ServicePoint.class,
new ServicePointId(provider.getUserId(), servicePoint.getServicePointNumber()));
assertTrue("Service point provider id and Provider provider id should be the same.",
servicePoint2.getProvider().getUserId() == provider.getUserId());
assertNotNull("Service point number can not be null", servicePoint2.getServicePointNumber());
assertEquals(servicePoint2.getProvider(), provider);
transaction.begin();
em.remove(servicePoint);
em.remove(provider);
transaction.commit();
ОБНОВЛЕНИЕ 2 - новая проблема в составном PK следующего отношения (3 столбца), а 2 из них являются составными FK. Я пытался походить на приведенное ниже решение и не мог понять, как написать ServicePointPhotoId @IdClass
@EmbeddedID
, так как это уменьшает дублирование всех атрибутов в двух классах и вероятность их рассинхронизации. Я всегда думал, что@IdClass
в спецификации соответствует методу, используемому в спецификации Container Managed Persistence до JPA. 09.06.2015