#java #spring-boot #hibernate #jpa #composite-primary-key
#java #spring-boot #спящий режим #jpa #составной первичный ключ
Вопрос:
Возможно ли в обычном JPA или гибернации составной ключ, где элементом составного ключа является последовательность, а другим элементом является сопоставленный с внешним ключом.
В моей таблице есть составной ключ, и его часть должна быть сгенерирована последовательностью. Я попробовал следующее, но это не сработало
class produit
@Entity
public class Produit{
@EmbeddedId
private ProduitClientPK id=new ProduitClientPK();
private Client client;
public ProduitClientPK getId() {
return id;
}
public void setId(ProduitClientPK id) {
this.id = id;
}
@JsonIgnore
@ManyToOne
@JoinColumn(name="FK_CLIENT")
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
составной ключ класса :
@Embeddable
public class ProduitClientPK implements Serializable {
private long fkproduit;
private long clientSeq;
@Column(name = "FK_PRODUIT")
@Id
public long getFkProduit() {
return fkproduit;
}
public void setFkProduit(long fkproduit) {
this.fkproduit= fkproduit;
}
@Column(name = "CLIENT_SEQ")
@Id
public long getclientSeq() {
return clientSeq;
}
public void setClientSeq(long clientSeq) {
this.clientSeq= clientSeq;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PolPolAvnEntityPK that = (PolPolAvnEntityPK) o;
return fkPolice == that.fkPolice amp;amp;
avnSeq == that.avnSeq;
}
@Override
public int hashCode() {
return Objects.hash(fkPolice, avnSeq);
}
}
клиент класса :
@Entity
public class Client {
private Long id;
private Set<Produit> produits;
@Id
@Column(name = "ID_PRODUIT")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<Produit> getProduits() {
return produits;
}
public void setProduits(Set<Produit> avenants) {
this.produits = produits;
}
public void addProduits(Produit produit){
produit.setClient(this);
produits.add(produit);
}
}
Комментарии:
1. Можете ли вы добавить
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
в свойProduitClientPK
2. Это сделано, но все равно не работает
3. Я не вижу этого в вашем примере
Ответ №1:
Ваша модель не имеет особого смысла, если я не понял ее неправильно. Почему вам нужно FK_PRODUIT
быть частью первичного ключа? Если вы используете последовательность для CLIENT_SEQ
, этого достаточно, чтобы сделать строку уникальной. Кроме того, разве это CLIENT_SEQ
значение не должно генерироваться при сохранении a Client
? IMO вы должны использовать что-то вроде следующего:
@Entity
public class Produit{
@Id
@GeneratedValue
private Long id;
private Client client;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@JsonIgnore
@ManyToOne
@JoinColumn(name="FK_CLIENT")
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
Ответ №2:
Я не так давно столкнулся с такой же проблемой. Было бы лучше не использовать @EmbeddedId в вашем случае, если вы хотите, чтобы одно из полей PK было сгенерировано вашей базой данных. Я не эксперт в гибернации, но, насколько я знаю, Hibernate не пытается устанавливать значения для полей идентификаторов, только если они помечены @GeneratedValue . Только эта аннотация может указывать Hibernate полагаться на последовательности базы данных. И вы не можете сделать это в встраиваемом классе.
Попробуйте использовать только одно поле @Id, если вы хотите, чтобы оно было сгенерировано.