Question

Est-il possible, dans les extensions JPA ou JPA + Hibernate simples, de déclarer une clé composite, où un élément de la clé composite est une séquence?

Ceci est ma classe composite:

@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;
    }

    //...
}

Je fournis déjà les valeurs pour application , entité , nativeId et nativeKey . Je veux construire une entité comme celle ci-dessous:

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

Et lorsque j'appelle em.persist (i1 ), je souhaite que le canonicalId soit généré et que l'intégration soit insérée.

Est-ce possible? Si oui, quel est le moyen simple? (Je préfère ne pas utiliser les clés fournies par l'application ni le SQL natif).

Était-ce utile?

La solution

Je pense que ce n'est pas possible avec une simple JPA.

Autres conseils

L'utilisation de @GeneratedValue pour des PK composites n'est pas spécifiée avec la spécification JPA 2

.

À partir de la spécification JPA:

  

11.1.17 Annotation GeneratedValue

     

L'annotation GeneratedValue fournit la spécification de   stratégies de génération pour les valeurs des clés primaires. le   L'annotation GeneratedValue peut être appliquée à une propriété de clé primaire ou   champ d'une entité ou d'une super-classe mappée en conjonction avec l'ID   annotation. [97] L'utilisation de l'annotation GeneratedValue est seulement   doit être pris en charge pour les clés primaires simples. Utilisation du   L'annotation GeneratedValue n'est pas prise en charge pour les clés primaires dérivées.

Notez que dans un scénario différent, vous pouvez avoir une entité parent avec une clé simple (@Id) qui utilise @GeneratedValue, puis une entité enfant qui a une clé composite qui inclut l'id généré à partir du parent, plus une autre colonne.

  • Attribuez à l'enfant une relation @ManyToOne avec l'entité parent afin qu'il hérite de l'ID généré dans une colonne FK.
  • Donnez ensuite à l'enfant une PK composite, via @IdClass spécifiée pour l'entité, plus deux colonnes @Id dans l'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) { //... }
}

Essayez comme ça:

@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;
}

De cette manière, au lieu d'utiliser une séquence, vous pouvez utiliser un tableau.

Je remarque qu'il apparaît que vous construisez une clé primaire composite comme ceci exemple . Alors que je cherchais un problème similaire dans ma propre base de données, je me demandais si vous pouviez peut-être appeler le sql directement comme suit:

select nextval ('hibernate_sequence')

Je suppose que ce serait tricher si; -)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top