2010-05-07 11 views
10

Tengo un componente asignado utilizando Hibernate. Si todos los campos del componente en la base de datos son nulos, el componente en sí mismo se establece en nulo por hibernación. Este es el comportamiento esperado y también lo que necesito.Hibernar colección vacía en el componente

El problema que tengo, es que cuando agrego una bolsa a ese componente, la bolsa se inicializa en una lista vacía. Esto significa que el componente tiene un valor no nulo ... lo que da como resultado la creación del componente.

alguna idea de cómo solucionar este problema?

<class name="foo.bar.Entity" table="Entity"> 
<id name="id" column="id"> 
    <generator class="native" /> 
</id> 

<property name="departure" column="departure_time" /> 
<property name="arrival" column="arrival_time" /> 

<component name="statistics"> 
    <bag name="linkStatistics" lazy="false" cascade="all" > 
     <key column="entity_id" not-null="true" /> 
     <one-to-many class="foo.bar.LinkStatistics" /> 
    </bag> 

    <property name="loggedTime" column="logged_time" /> 

    ... 
</component> 

Una criterios con Restirctions.isNull ("estadísticas") no devuelven los valores esperados.

+0

Agregue información sobre el contexto: ¿Quién establece el componente como nulo? ¿Cuál es el componente del que estás hablando? ¿Cuál es el contenedor? –

+0

Aaron, Hibernate deja la propiedad del componente (estadísticas, en la clase Entity) en nulo. –

+0

Parece ser un problema bastante viejo, pero lo tengo también y no pude encontrar ninguna solución. ¿Tuviste un poco de suerte mientras tanto? – Martin

Respuesta

0

no puedo comprobar esto, pero aquí está una idea:

public void setListProperty(List list) { 
    if (list == null || list.size() == 0) { 
    this.listProperty = null; 
    } else { 
    this.listProperty = list; 
    } 
} 

Obviamente no es ideal, pero podría ser una solución para usted ...

+0

¿Este enfoque realmente funciona para usted? Desde mi experiencia, tales trucos en setters conducen a la excepción "otra colección ya está asociada con la sesión" en Hibernate (porque Hibernate recordará la colección vacía que pretendía asociar con la entidad padre). Por lo tanto, el código anterior funcionará cuando la entidad se separe (la sesión con la que se cargó se cerró), pero de lo contrario fallará. Usar 'null' en getter es mucho mejor :) –

1

El problema básico es que Hibernate no puede distinguir entre colecciones nulas y colecciones vacías, por lo que las trata como vacías: no nulas.

Le sugiero que cambie su componente de estadísticas a una entidad real en su lugar. Entonces su clase foo.bar.Entity tiene una referencia, que puede ser nula. Esto no es ideal porque tendrás que crear otra tabla para almacenar la entidad Statistics, pero si quieres la distinción semántica nula versus vacía, esa es una forma de obtenerla.

+0

Correcto. El concepto de recopilación realmente no existe en el RDBMS, por lo que Hibernate (o cualquier ORM) tiene que hacer * algo *. –

0

Quizás esto pueda ayudar. No resuelve el problema de distinguir entre bolsa vacía y vacía, pero es una solución. Como sabrá, puede introducir un interceptor en su sesión que pueda interceptar ciertas acciones, como guardar o actualizar entidades, luego puede usar este interceptor para verificar el estado de su componente y, si está vacío, anularlo nuevamente para que Hibernate gane guardar valores vacíos here es los documentos.

Cuestiones relacionadas