Hibernate: ¿cuál es insertable = false, actualizable = false pertenecen en constelaciones claves primarias compuestas implican claves externas?

StackOverflow https://stackoverflow.com/questions/3669883

Pregunta

En la aplicación de las claves primarias compuestas en hibernación o de otros ORM hay hasta tres lugares donde poner el insertable = false, actualizable = false en constelaciones claves primarias compuestas que utilizan las relaciones de identificación (FKS que forman parte de la PK):

  1. en la clase PK composite anotación @Column (sólo clases @Embeddable) o
  2. En la asociación de clase entidad @ JoinColumn / s anotación o
  3. En la clase de entidad redundante @Column anotación de PK propiedad (clases @IdClass solamente)

El tercero es la única manera de hacerlo con @IdClass y JPA 1.0 AFAIK. Ver http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_Relationships. Voy a considerar sólo los casos 1. y 2.

Q: ¿Qué camino es el lugar preferido para poner el "insertable = false, actualizable = false" para general?

he tenido problemas con Hibernate en relación con esta cuestión. Por ejemplo, Hibernate 3.5.x se quejará de la tabla cremalleras

CREATE TABLE Zips
(
  country_code CHAR(2),
  code VARCHAR(10),
  PRIMARY KEY (country_code, code),
  FOREIGN KEY (country_code) REFERENCES Countries (iso_code)
)

por:

org.hibernate.MappingException: Repeated column in mapping for entity: com.kawoolutions.bbstats.model.Zip column: country_code (should be mapped with insert="false" update="false")
org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:676)
org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:698)
...

Como se puede ver la columna de la country_code es a la vez PK y FK. Aquí están sus clases:

clase de entidad:

@Entity
@Table(name = "Zips")
public class Zip implements Serializable
{
    @EmbeddedId
    private ZipId id;

    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country = null;
...
}

Compuesto clase PK:

@Embeddable
public class ZipId implements Serializable
{
    @Column(name = "country_code", insertable = false, updatable = false)
    private String countryCode;

    @Column(name = "code")
    private String code;
...
}

Al poner el insertable = false, actualizable = false en @JoinColumn de la asociación de la clase entidad desaparecer todas las excepciones y fino que todo funcione. Sin embargo, no veo por qué el código anterior no debería estar trabajando. Podría ser Hibernate tener problemas con esto. Es lo descrito un error de hibernación, ya que no parece para evaluar @Column "insertable = false, actualizable = false"?

En esencia, ¿cuál es la forma estándar de la APP, la mejor práctica, o preferencia dónde poner "insertable = false, actualizable = false"?

¿Fue útil?

Solución

Déjeme contestar paso a paso.

1. ¿Cuándo necesita `insertable = false, actualizable = false`?

Veamos el siguiente mapeo,

public class Zip {

    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country = null

    @Column(name = "country_code")
    private String countryCode;

}

Aquí nos estamos refiriendo a la misma columna en la tabla utilizando dos propiedades diferentes. En el siguiente código:

Zip z = new Zip();

z.setCountry(getCountry("US"));
z.setCountryCode("IN");

saveZip(z);

¿Qué va a hacer aquí ?? hibernación

Para evitar este tipo de inconsistencia, de hibernación le pide que especifique el punto de naves relación actualización. Lo que significa puede hacer referencia a la misma columna en el número n tabla de tiempos, pero sólo uno de ellos puede ser utilizado para la actualización y todos los demás sólo se leerán .

2. ¿Por qué se quejan de que su hibernación mapeo?

En la clase Zip se está refiriendo a la clase ZipId Identificación incrustado que contiene de nuevo el código de país. Al igual que en el escenario anterior ahora usted tiene una posibilidad de actualizar la columna de la counry_code de dos lugares. Por lo tanto error dado por Hibernate es adecuada.

3. Cómo fijarlo en su caso?

No. Lo ideal sería que usted quiere que su clase ZipId para generar la identificación, por lo que no debe agregar a la insertable = false, updatable = false countryCode dentro del ZipId. Así que la solución es la siguiente modificar la asignación country en su clase Zip como abajo,

@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code",
insertable =  false, updatable = false)
private Country country;

Espero que esto ayuda a su comprensión.

Otros consejos

También puede resolver este problema mediante el uso de anotación @PrimaryKeyJoinColumn. Las especifica PrimaryKeyJoinColumn anotación una columna de clave principal que se utiliza como una clave externa para unirse a otra mesa.

La anotación PrimaryKeyJoinColumn se utiliza para unir la tabla principal de la subclase entidad en la estrategia de mapeo unido a la tabla principal de su superclase; se utiliza dentro de una anotación SecondaryTable unirse a una mesa secundaria a una tabla principal; y se puede usar en un mapeo OneToOne en el que la clave primaria de la entidad de referencia se utiliza como una clave externa a la entidad referenciada. Si no se especifica ninguna anotación PrimaryKeyJoinColumn para una subclase de la estrategia de mapeo Macizo, las columnas de clave externa se supone que tienen los mismos nombres que las columnas de clave principal de la tabla principal de la superclase.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top