Frage

Ist es möglich, in einfachen JPA oder PPV + Hibernate-Erweiterungen einen zusammengesetzten Schlüssel zu erklären, wo ein Element des zusammengesetzten Schlüssels ist eine Sequenz?

Das ist mein Verbund Klasse:

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

    //...
}

Ich liefere bereits die Werte für application, entity, nativeId und nativeKey. Ich möchte im Folgenden ein Unternehmen wie das konstruieren:

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

Und wenn ich em.persist(i1 nennen), ich mag, dass der canonicalId erzeugt wird und die Integration eingefügt wird.

Ist das möglich? Wenn ja, was ist der einfache Weg? (Ich ziehe nicht die Anwendung bereitgestellte Schlüssel oder native SQL verwenden).

War es hilfreich?

Lösung

Ich glaube, dass dies nicht möglich mit einfacher JPA ist.

Andere Tipps

Mit @GeneratedValue für Composite-PKs nicht angegeben withi JPA 2 spec.

Von der JPA-Spezifikation:

  

11.1.17 GeneratedValue Annotation

     

Die GeneratedValue Anmerkung sieht die Spezifikation von   Generation Strategien für die Werte des Primärschlüssels. Das   GeneratedValue Annotation kann auf eine Primärschlüsseleigenschaft angewandt werden, oder   Feld einer Einheit oder kartiert geordnete Klasse in Verbindung mit dem Id   Anmerkung. [97] Die Verwendung der GeneratedValue Anmerkung ist nur   erforderlich unterstützt für einfache Primärschlüssel werden. Die Nutzung des   GeneratedValue Anmerkung wird nicht für abgeleitete Primärschlüssel unterstützt.

Beachten Sie, dass unter einem anderen Szenario Sie eine übergeordnete Einheit mit einem einfachen PK haben können (@Id), die @GeneratedValue verwendet und dann ein Kind Einheit hat, die eine Verbund PK hat, die das erzeugte Id aus dem übergeordneten enthält, sowie eine andere Spalte.

  • Geben Sie dem Kind eine @ManyToOne Beziehung zur Muttergesellschaft, so dass es die erzeugte ID in einer FK Spalte erbt.
  • Dann das Kind gibt einen Verbund PK, über @IdClass gegen das Unternehmen angegeben, plus zwei @Id Spalten innerhalb des Unternehmens.
@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) { //... }
}

Versuchen Sie wie folgt aus:

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

Auf diese Weise, anstatt eine Folge der Verwendung können Sie eine Tabelle verwenden.

Ich stelle fest, dass es Ihr Aufbau eines zusammengesetzten Primärschlüssel wie dies erscheint Beispiel . Während ich bei einem ähnlichen Problem in meiner eigenen Datenbank Stossen fragte ich mich, ob vielleicht könnten Sie die SQL-Aufruf direkt wie:

select nextval ('hibernate_sequence')

Ich nehme an, dass würde zwar betrügen; -)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top