2010-05-07 8 views
10

J'ai un composant mappé en utilisant Hibernate. Si tous les champs du composant dans la base de données sont NULL, le composant lui-même est défini sur null par Hibernate. C'est le comportement attendu et aussi ce dont j'ai besoin.hibernate collection vide dans le composant

Le problème que j'ai, c'est que lorsque j'ajoute un sac à ce composant, le sac est initialisé à une liste vide. Cela signifie que le composant a une valeur non nulle ... entraînant la création du composant.

Une idée pour résoudre ce problème?

<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> 

Un critère avec Restirctions.isNull ("statistiques") ne renvoie les valeurs attendues.

+0

Veuillez ajouter des informations sur le contexte: Qui définit le composant sur null? Quel est le composant dont vous parlez? Quel est le conteneur? –

+0

Aaron, Hibernate laisse la propriété component (statistiques, dans la classe Entity) à null. –

+0

Semble être un problème plutôt ancien mais je l'ai aussi bien et n'ai pu trouver aucune solution. Avez-vous eu de la chance en attendant? – Martin

Répondre

0

Je ne peux pas vérifier cela, mais voici une idée:

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

De toute évidence pas idéal, mais peut-être une solution pour vous ...

+0

Est-ce que cette approche fonctionne vraiment pour vous? D'après mon expérience, de tels trucs dans les setters mènent à l'exception "une autre collection est déjà associée à la session" dans Hibernate (car Hibernate se souviendra de la collection vide qu'il avait l'intention d'associer à l'entité parente). Donc, le code ci-dessus fonctionnera quand l'entité est détachée (la session avec laquelle elle était chargée a été fermée), mais échouera autrement. Utiliser 'null' dans getter est beaucoup mieux :) –

1

Le problème fondamental est que Hibernate ne peut pas distinguer entre des collections nulles et des collections vides, donc il les traite tous deux comme vides: non nul.

Je vous suggère de changer votre composant Statistics en une entité réelle à la place. Alors votre classe foo.bar.Entity a une référence, qui peut être nulle. Ce n'est pas idéal car vous devrez créer une autre table pour stocker l'entité Statistics, mais si vous voulez la distinction sémantique nulle vs vide, c'est un moyen de l'obtenir.

+0

Correct. Le concept de collection n'existe pas vraiment dans le SGBDR, donc Hibernate (ou n'importe quel ORM) doit faire * quelque chose *. –

0

Peut-être que cela peut aider. Il ne résout pas le problème de la distinction entre le sac vide et vide, mais c'est une solution de contournement. Comme vous le savez, vous pouvez introduire un intercepteur à votre session qui peut intercepter certaines actions comme enregistrer ou mettre à jour des entités, vous pouvez utiliser cet intercepteur pour vérifier l'état de votre composant et le rendre nul pour que hibernate gagne ne sauvegardez pas les valeurs vides. here est la docs.

Questions connexes