unidirectional one many example hibernate-mapping hbm hibernate-onetomany hbmxml

hibernate mapping - one - ¿Cómo puedo asignar “insert=''false'' update=''false''” en una propiedad-clave de ID compuesta que también se usa en un FK de uno a varios?



hibernate one to many unidirectional xml mapping example (2)

"Dino TW" ha proporcionado el enlace al comentario Excepción de asignación de hibernación: Columna repetida en la asignación para la entidad que tiene la información vital.

Las sugerencias de enlace para proporcionar "inverse = true" en el mapeo del conjunto, lo probé y realmente funciona. Es una situación tan rara en la que se combinan una clave Set y una Compuesta. Hacer inverso = verdadero, dejamos la inserción y actualización de la tabla con clave Compuesta para que sea atendido por sí mismo.

A continuación puede ser el mapa requerido,

<class name="com.example.CompanyEntity" table="COMPANY"> <id name="id" column="COMPANY_ID"/> <set name="names" inverse="true" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> <key column="COMPANY_ID" not-null="true"/> <one-to-many entity-name="vendorName"/> </set> </class>

Estoy trabajando en una base de código heredada con un esquema de base de datos existente. El código existente utiliza SQL y PL / SQL para ejecutar consultas en la base de datos. Se nos ha asignado la tarea de hacer que una pequeña parte del motor de base de datos del proyecto sea independiente (al principio, cambie todo eventualmente). Hemos elegido utilizar los archivos de mapeo Hibernate 3.3.2.GA y "* .hbm.xml" (a diferencia de las anotaciones). Desafortunadamente, no es posible cambiar el esquema existente porque no podemos retroceder ninguna característica heredada.

El problema que encuentro es cuando intento mapear una relación unidireccional de uno a muchos donde el FK también forma parte de una PK compuesta. Aquí están las clases y el archivo de mapeo ...

CompanyEntity.java

public class CompanyEntity { private Integer id; private Set<CompanyNameEntity> names; ... }

CompanyNameEntity.java

public class CompanyNameEntity implements Serializable { private Integer id; private String languageId; private String name; ... }

CompanyNameEntity.hbm.xml

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.jboss.org/dtd/hibernate/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.example"> <class name="com.example.CompanyEntity" table="COMPANY"> <id name="id" column="COMPANY_ID"/> <set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> <key column="COMPANY_ID"/> <one-to-many entity-name="vendorName"/> </set> </class> <class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME"> <composite-id> <key-property name="id" column="COMPANY_ID"/> <key-property name="languageId" column="LANGUAGE_ID"/> </composite-id> <property name="name" column="NAME" length="255"/> </class> </hibernate-mapping>

Este código funciona bien para SELECCIONAR e INSERTAR una empresa con nombres. Encontré un problema cuando intenté actualizar un registro existente. Recibí una excepción BatchUpdateException y después de revisar los registros de SQL, vi que Hibernate intentaba hacer algo estúpido ...

update COMPANY_NAME set COMPANY_ID=null where COMPANY_ID=?

Hibernate intentaba desasociar registros secundarios antes de actualizarlos. El problema es que este campo es parte de la PK y no acepta nulos. Encontré que la solución rápida para que Hibernate no haga esto es agregar "not-null = ''true''" al elemento "clave" en la asignación principal. Así que ahora puede mapearse así ...

CompanyNameEntity.hbm.xml

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.jboss.org/dtd/hibernate/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.example"> <class name="com.example.CompanyEntity" table="COMPANY"> <id name="id" column="COMPANY_ID"/> <set name="names" table="COMPANY_NAME" cascade="all-delete-orphan" fetch="join" batch-size="1" lazy="false"> <key column="COMPANY_ID" not-null="true"/> <one-to-many entity-name="vendorName"/> </set> </class> <class entity-name="companyName" name="com.example.CompanyNameEntity" table="COMPANY_NAME"> <composite-id> <key-property name="id" column="COMPANY_ID"/> <key-property name="languageId" column="LANGUAGE_ID"/> </composite-id> <property name="name" column="NAME" length="255"/> </class> </hibernate-mapping>

Esta cartografía da la excepción ...

org.hibernate.MappingException: Repeated column in mapping for entity: companyName column: COMPANY_ID (should be mapped with insert="false" update="false")

Mi problema ahora es que he intentado agregar estos atributos al elemento de propiedad clave, pero la DTD no lo admite. También he intentado cambiarlo a un elemento clave de muchos a uno, pero tampoco funcionó. Asi que...

¿Cómo puedo asignar "insert = ''false'' update = ''false''" en una propiedad-clave de ID compuesta que también se usa en un FK de uno a varios?


Creo que la anotación que estás buscando es:

public class CompanyName implements Serializable { //... @JoinColumn(name = "COMPANY_ID", referencedColumnName = "COMPANY_ID", insertable = false, updatable = false) private Company company;

Y debería poder usar asignaciones similares en un hbm.xml como se muestra aquí (en 23.4.2):

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/example-mappings.html