2010-04-07 2 views
2

J'ai une entité "Groupe" avec un ID affecté qui est ajouté à un agrégat afin de le conserver. Cela provoque un problème car NHibernate ne peut pas dire s'il est nouveau ou existant. Pour remédier à ce problème, j'ai modifié le mappage pour que l'entité Group utilise un verrouillage optimiste sur une colonne de version timestamp sql. Cela a causé un nouveau problème. Le groupe a un sac de sous objets. Ainsi, lorsque NHibernate vide un nouveau groupe dans la base de données, il crée d'abord l'enregistrement Groupe dans la table Groupes, puis insère chacun des sous-objets, puis effectue une mise à jour des enregistrements Groupe pour mettre à jour la valeur d'horodatage. Toutefois, le sql généré pour terminer la mise à jour n'est pas valide lorsque le mappage est à la fois dynamic-update = "true" et optimistic-lock = "version".NHibernate mapping avec optimistic-lock = "version" et dynamic-update = "true" génère une instruction de mise à jour invalide

Voici la cartographie:

<class xmlns="urn:nhibernate-mapping-2.2" dynamic-update="true" mutable="true" optimistic-lock="version" name="Group" table="Groups"> 
    <id name="GroupNumber" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="GroupNumber" length="5" /> 
     <generator class="assigned" /> 
    </id> 
    <version generated="always" name="Timestamp" type="BinaryBlob" unsaved-value="null"> 
     <column name="TS" not-null="false" sql-type="timestamp" /> 
    </version> 
    <property name="UID" update="false" type="System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="GroupUID" unique="true" /> 
    </property> 
    <property name="Description" type="AnsiString"> 
     <column name="GroupDescription" length="25" not-null="true" /> 
    </property> 
    <bag access="field.camelcase-underscore" cascade="all" inverse="true" lazy="true" name="Assignments" mutable="true" order-by="GroupAssignAssignment"> 
     <key foreign-key="fk_Group_Assignments"> 
     <column name="GroupNumber" /> 
     </key> 
     <one-to-many class="Assignment" /> 
    </bag> 
    <many-to-one class="Aggregate" name="Aggregate"> 
     <column name="GroupParentID" not-null="true" /> 
    </many-to-one> 
    </class> 
</hibernate-mapping> 

Lorsque le mappage inclut à la fois la mise à jour dynamique et le verrou optimiste, le SQL généré est:

UPDATE groups SET WHERE GroupNumber = 11111 AND TS=0x00000007877 

Ceci est évidemment invalide car il n'y a pas de SET déclarations. Si je supprime la partie de mise à jour dynamique, tout est mis à jour au cours de cette instruction de mise à jour à la place. Cela rend la déclaration valide, mais plutôt inutile.

Quelqu'un at-il déjà vu ce problème? Est-ce que je manque quelque chose?

Merci, Steve

+0

pouvez-vous créer un testcase autonome? –

Répondre

0

Essayer de définir l'attribut unsaved-value dans l'élément id; Cela devrait permettre à NHibernate de faire la distinction entre les enregistrements nouveaux et existants et de contourner le problème de l'horodatage.

<id name="GroupNumber" unsaved-value="" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 

The documentation me porte à croire que cela devrait par défaut à une chaîne vide, mais il vaut la peine d'essayer.

+0

Cela n'a pas semblé faire une différence dans la requête générée. – SteveBering

1

J'ai eu exactement le même problème, et il m'a fallu un âge pour trébucher sur la documentation avant que je l'ai finalement mis au travail. Vous devez définir l'attribut optimistic-lock sur votre élément de sac sur false. Cela empêchera NH de marquer le parent pour la mise à jour lorsqu'aucune propriété modifiable n'a été modifiée. J'espère que cela fonctionne pour vous.

Questions connexes