Составной ключ JPA с последовательностью в spring boot JPA

#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, если вы хотите, чтобы оно было сгенерировано.