Domanda

È possibile nelle normali estensioni JPA o JPA + Hibernate dichiarare una chiave composita, dove un elemento della chiave composita è una sequenza?

Questa è la mia classe composita:

@Embeddable
public class IntegrationEJBPk implements Serializable {

    //...


    @ManyToOne(cascade = {}, fetch = FetchType.EAGER)
    @JoinColumn(name = "APPLICATION")
    public ApplicationEJB getApplication() {
        return application;
    }


    @Column(name = "ENTITY", unique = false, nullable = false, insertable = true, updatable = true)
    public String getEntity() {
        return entity;
    }

    @GeneratedValue(strategy = GenerationType.AUTO, generator = "INTEGRATION_ID_GEN")
    @SequenceGenerator(name = "INTEGRATION_ID_GEN", sequenceName = "OMP_INTEGRATION_CANONICAL_SEQ")
    @Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true)
    public String getCanonicalId() {
        return canonicalId;
    }

    @Column(name = "NATIVE_ID", unique = false, nullable = false, insertable = true, updatable = true)
    public String getNativeId() {
        return nativeId;
    }

    @Column(name = "NATIVE_KEY", unique = false, nullable = false, insertable = true, updatable = true)
    public String getNativeKey() {
        return nativeKey;
    }

    //...
}

Fornisco già i valori per application , entity , nativeId e nativeKey . Voglio costruire un'entità come quella qui sotto:

IntegrationEJB i1 = new IntegrationEJB();
i1.setIntegrationId(new IntegrationEJBPk());
i1.getIntegrationId().setApplication(app1);
i1.getIntegrationId().setEntity("Entity");
i1.getIntegrationId().setNativeId("Nid");
i1.getIntegrationId().setNativeKey("NK");

E quando chiamo em.persist (i1 ), voglio che canonicalId sia generato e che l'integrazione sia inserita.

È possibile? Se è così, qual è il modo semplice? (Preferisco non usare chiavi fornite dall'applicazione o sql nativo).

È stato utile?

Soluzione

Credo che ciò non sia possibile con l'APP semplice.

Altri suggerimenti

L'uso di @GeneratedValue per PK compositi non è specificato con le specifiche JPA 2

Dalle specifiche dell'APP:

  

11.1.17 Annotazione GeneratedValue

     

L'annotazione GeneratedValue fornisce le specifiche di   strategie di generazione per i valori delle chiavi primarie. Il   L'annotazione GeneratedValue può essere applicata a una proprietà chiave primaria o   campo di un'entità o superclasse mappata insieme all'ID   annotazione. [97] L'uso dell'annotazione GeneratedValue è solo   richiesto per essere supportato per semplici chiavi primarie. Uso del   L'annotazione GeneratedValue non è supportata per le chiavi primarie derivate.

Tieni presente che in uno scenario diverso, puoi avere un'entità padre con un PK semplice (@Id) che utilizza @GeneratedValue e quindi avere un'entità figlio che ha un PK composito che include l'ID generato dal padre, oltre a un'altra colonna.

  • Assegna al figlio una relazione @ManyToOne con l'entità padre, in modo che erediti l'ID generato in una colonna FK.
  • Quindi assegna al figlio un PK composito, tramite @IdClass specificato rispetto all'entità, più due colonne @Id all'interno dell'entità.
@Entity
public class ParentEntity {
       @Id
       @GenerateValue(IDENTITY) // If using DB auto-increment or similar
       int id;

       // ...
}
@Entity
@IdClass(ChildId.class)
public class ChildEntity {
   // The child table will have a composite PK:
   // (parent_ID, child_name)
       @Id 
       @ManyToOne
       int parentEntity;
       @Id
       String childName;

       String favoriteColor;  // plus other columns

       // ...

}
// child Id attributes have the same name as the child entity
// however the types change to match the underlying PK attributes 
// (change ParentEntity to int)
 public class ChildId implements Serializable {
        int parentEntity;
        String childName;

        public ChildId() { //... }

        // Add extra constructor & remove setter methods so Id objects are immutable
        public ChildId(int parentEntity, String childName) { //... }


        public int getParentEntity() { //... }
        // make Id objects immutable:
        //  public void setParentEntity(int parentEntity) { //... }
        public String getChildName() { //... }
        //  public void setChildName(String childName) { //... }
}

Prova in questo modo:

@TableGenerator(name = "canonicalKeys", allocationSize = 1, initialValue = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "canonicalKeys")
@Column(name = "CANONICAL_ID", unique = false, nullable = false, insertable = true, updatable = true)
public String getCanonicalId() {
    return canonicalId;
}

In questo modo invece di usare una sequenza puoi usare una tabella.

Ho notato che sembra che tu stia costruendo una chiave primaria composita come questa esempio . Mentre cercavo un problema simile nel mio database, mi chiedevo se forse potevi chiamare sql direttamente come:

seleziona nextval ('hibernate_sequence')

Suppongo che sarebbe barare però ;-)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top