tabla - recorrer lista hibernate
Asignaciones de Hibernate con un discriminador (4)
Discriminador como entero
Normalmente, si especifica el valor discriminador como entero en la subclase, obtiene el error
No se pudo formatear el valor del discriminador ''TYPE'' a la cadena SQL usando el (...)
Si desea utilizar el discriminador como un valor entero, primero debe especificarlo para la clase base como un entero estableciendo el atributo discriminador-valor en el elemento de clase:
<class name="AdminNotes" table="admin_notes" abstract="true" discriminator-value= "-1">
Esto reemplaza el comportamiento predeterminado donde el discriminador es un nombre de clase cuando no se encuentra un valor.
<hibernate-mapping package="com.tlr.finance.mappings">
<class name="AdminNotes" table="admin_notes" abstract="true" discriminator-value= "-1">
<id name="adminNoteId" column="admin_note_id" type="integer">
<generator class="identity" />
</id>
<discriminator column="note_type" type="integer" />
<!-- Make this property an enumerated type. It is the discriminator. -->
<property name="adminNoteType" column="note_type" type="string" not-null="true" />
<property name="adminNote" column="note" type="string" not-null="true" />
<property name="adminNoteAdded" column="note_date" type="timestamp"
not-null="true" />
<subclass name="AdminNotes" discriminator-value="0" entity-name="project">
<many-to-one name="noteObject" column="object_id" class="PsData" /><!-- Project -->
</subclass>
<subclass name="AdminNotes" discriminator-value="1" entity-name="user">
<!-- Rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="Timekeep" /><!-- user -->
</subclass>
<subclass name="AdminNotes" discriminator-value="2" entity-name="costCenter">
<!-- Rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="CostCenter" /><!-- cost center -->
</subclass>
</class>
</hibernate-mapping>
Tengo una tabla con un campo que puede apuntar a una clave externa en una de las otras 3 tablas según el valor del descriminador (Project, TimeKeep o CostCenter. Por lo general, esto se implementa con subclases, y me pregunto si lo que tengo a continuación, tenga en cuenta que el nombre de la subclase es el mismo que el de la clase padre y la propiedad noteObject está asignada a una variable de instancia de tipo java.lang.Object por lo que debe aceptar un objeto Project, TimeKeep o CostCenter siempre que lo lancemos a el tipo correcto. ¿Hibernate permitirá esto? Gracias.
<hibernate-mapping package="com.tlr.finance.mappings">
<class name="AdminNotes" table="admin_notes">
<id name="adminNoteId" column="admin_note_id" type="integer">
<generator class="identity" />
</id>
<discriminator column="note_type" type="string" />
<!-- make this property an enumerated type. It is the discriminator -->
<property name="adminNoteType" column="note_type" type="string" not-null="true" />
<property name="adminNote" column="note" type="string" not-null="true" />
<property name="adminNoteAdded" column="note_date" type="timestamp"
not-null="true" />
<subclass name="AdminNotes" discriminator-value="project" >
<many-to-one name="noteObject" column="object_id" class="PsData" /><!-- Project -->
</subclass>
<subclass name="AdminNotes" discriminator-value="user" >
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="Timekeep" /><!-- user -->
</subclass>
<subclass name="AdminNotes" discriminator-value="costCenter" >
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="CostCenter" /><!-- cost center -->
</subclass>
</class>
</hibernate-mapping>
AFAIK, puede reutilizar nombres de clases Java para mapeos de subclases si usa nombres de entidades.
Pruebe el mapeo a continuación. Aquí el mapeo de la superclase en sí es abstracto. Las subclases usan la misma clase de Java y un nombre de entidad para cada subclase. Es posible que deba colocar el nombre de la entidad en el mapeo de la superclase. Sin embargo, yo personalmente usaría subclases de Java separadas para cada mapeo de subclases, como con los nombres de las entidades tendría que proporcionar nombre-entidad cuando necesita persistir un objeto a través de la API de sesión, o implementar resolución de nombres de entidad en Tuplizer ( Hibernate 3.3 .2) basado en el campo adminNoteType.
<hibernate-mapping package="com.tlr.finance.mappings">
<class name="AdminNotes" table="admin_notes" abstract="true">
<id name="adminNoteId" column="admin_note_id" type="integer">
<generator class="identity" />
</id>
<discriminator column="note_type" type="string" />
<!-- Make this property an enumerated type. It is the discriminator. -->
<property name="adminNoteType" column="note_type" type="string" not-null="true" />
<property name="adminNote" column="note" type="string" not-null="true" />
<property name="adminNoteAdded" column="note_date" type="timestamp"
not-null="true" />
<subclass name="AdminNotes" discriminator-value="project" entity-name="project">
<many-to-one name="noteObject" column="object_id" class="PsData" /><!-- Project -->
</subclass>
<subclass name="AdminNotes" discriminator-value="user" entity-name="user">
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="Timekeep" /><!-- user -->
</subclass>
<subclass name="AdminNotes" discriminator-value="costCenter" entity-name="costCenter">
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="CostCenter" /><!-- cost center -->
</subclass>
</class>
</hibernate-mapping>
En lugar de tratar de usar las capacidades de herencia para obtener la referencia a la clase correcta, en su lugar debería considerar usar el tipo de correlación <any/>
donde use el tipo de note_type
para determinar el tipo al que se está object_id
el object_id
y establecer así su valor de noteObject
la referencia de objeto adecuada.
Para detalles sobre <any/>
, vea '' Cualquier tipo de mapeo '' en la documentación de NHibernate , y la entrada del blog NHibernate Mapping .
Los discriminadores se utilizan para almacenar jerarquías de clases en una sola tabla. Lo que tienes allí es una sola clase con múltiples significados.
El elemento es necesario para la persistencia polimórfica utilizando la estrategia de mapeo de tabla por jerarquía de clases y declara una columna discriminatoria de la tabla. La columna del discriminador contiene valores de marcador que le dicen a la capa de persistencia qué subclase crear para una fila en particular.
No creo que puedas usar una sola clase AdminNote para cada uno de esos diferentes significados. El discriminador se usa en el nivel de la base de datos para ayudar a distinguir una subclase de otra; en realidad, no es parte del modelo de objetos de Java.
Tendrá que definir múltiples subclases de AdminNote, una para cada valor discriminador.