with primary one many foreign example data java hibernate jpa composite-key

java - primary - spring entity composite key



Clave compuesta JPA+secuencia (4)

Pruebe de esta manera:

@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 esta forma, en lugar de usar una secuencia, puedes usar una tabla.

¿Es posible en extensiones simples JPA o JPA + Hibernate declarar una clave compuesta, donde un elemento de la clave compuesta es una secuencia?

Esta es mi clase compuesta:

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

Ya proporciono los valores para application , entity , nativeId y nativeKey . Quiero construir una entidad como la siguiente:

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

Y cuando llamo a em.persist(i1 ), quiero que se genere canonicalId y se inserte la integración.

es posible? Si es así, ¿cuál es la manera simple? (Prefiero no usar claves proporcionadas por la aplicación o SQL nativo).


Creo que esto no es posible con JPA simple.


Observé que parece que tu edificio es una clave primaria compuesta como en este ejemplo . Mientras investigaba un problema similar en mi propia base de datos, me preguntaba si tal vez podrías llamar al sql directamente así:

select nextval (''hibernate_sequence'')

Supongo que eso sería hacer trampa ;-)


El uso de @GeneratedValue para compuestos PK no se especifica con la especificación JPA 2.

Desde la especificación JPA:

11.1.17 Anotación GeneratedValue

La anotación GeneratedValue proporciona la especificación de estrategias de generación para los valores de las claves primarias. La anotación GeneratedValue se puede aplicar a una propiedad o campo de clave principal de una entidad o superclase mapeada junto con la anotación Id. [97] El uso de la anotación GeneratedValue solo se requiere para ser compatible con claves primarias simples. El uso de la anotación GeneratedValue no es compatible con las claves primarias derivadas.

Tenga en cuenta que bajo un escenario diferente, puede tener una entidad principal con un PK simple (@Id) que use @GeneratedValue, y luego tener una entidad hija que tenga un PK compuesto que incluya el Id generado del padre, más otra columna.

  • Otorgue al niño una relación @ManyToOne con la entidad principal, de modo que herede la ID generada en una columna FK.
  • Luego, déle al niño una PK compuesta, a través de @IdClass especificada contra la entidad, más dos columnas @Id dentro de la entidad.

@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) { //... } }